Die Einrichtung, Schritt für Schritt
Jeder Ausschnitt hier ist zum Einfügen bereit. Die Zahlen — Kontingente, Grenzen, Standardwerte, Feldnamen — stammen aus dem laufenden Code: diese Seite und der Server sagen dasselbe.
Erste Schritte
Holen Sie sich Ihren Schlüssel
Alles hier außer den RSS-Feeds verwendet einen API-Schlüssel. Öffne dein Konto, Abschnitt Entwickler-API, und kopiere ihn. Der kostenlose Plan benötigt keine Karte.
Der Schlüssel trägt deinen Plan, und dein Plan trägt deine täglichen Volumen. Zwei Zähler laufen nebeneinander: einer für die REST-API, einer für den MCP-Server. Ein Editor, der ein paar Fragen stellt, greift nie auf dein API-Budget zu.
Was brauche ich?
| Du möchtest… | Verwenden |
|---|---|
| Fragen Sie Ihren Editor | MCP-Server |
| Abfragen Sie die Daten aus Ihrem eigenen Code | REST API |
| Informiert werden, wenn sich etwas ändert | Webhooks |
| In n8n, Zapier oder Make integrieren | Automatisierungen |
| Überprüfen Sie Abhängigkeiten bei jedem Pull-Request | GitHub Action |
| Folgen Sie in einem Reader, kein Schlüssel | RSS-Feeds |
MCP-Server
Der MCP-Server, kurz erklärt
MCP (Model Context Protocol) ist eine standardisierte Methode für einen KI-Assistenten, um einen externen Dienst aufzurufen. Sie fügen eine Adresse in Ihren Client ein, und der Assistent erhält fünf Werkzeuge, die er während Ihrer Arbeit verwenden kann. Diese Werkzeuge fragen den olud.ai-Katalog ab: Open-Source-KI-Projekte, KI-Modelle mit ihren Preisen und Open-Source-Alternativen zu kommerziellen Produkten.
| Fakt | Wert |
|---|---|
| Endpunkt | https://olud.ai/mcp.php |
| Methode | POST, JSON-RPC 2.0. GET gibt 405 zurück (siehe unten) |
| Transport | Streambares HTTP, ein Endpunkt, kein SSE-Stream |
| Protokollversion | 2025-06-18. Wenn der Client nach 2025-03-26 oder 2024-11-05 fragt, antwortet der Server in dieser Version |
| Serverversion | 1.0.0 |
| Sitzung | Keine. Keine Mcp-Session-Id zu speichern, nichts zu verfallen, nichts zu reconnecten |
| Fähigkeiten | nur Werkzeuge. resources/list, resources/templates/list und prompts/list antworten mit leeren Listen anstelle eines Fehlers |
| Auth | X-Api-Key-Anforderungsheader. Optional |
| Batching | Nicht unterstützt. Ein JSON-RPC-Array wird mit HTTP 400 abgelehnt |
Der Server liest. Das einzige, was er schreibt, ist Ihr täglicher Aufrufzähler.
Einrichten, Client für Client
Die gleiche URL für jeden Client: https://olud.ai/mcp.php. Der Schlüssel wird im X-Api-Key-Header übertragen. Ohne Schlüssel antwortet der Server trotzdem, mit einer kleineren Erlaubnis (25 Aufrufe pro Tag und IP, 5 Ergebnisse pro Aufruf). Ihr Schlüssel und ein bereit zum Einfügen Block befinden sich in Ihrem Konto, Abschnitt MCP-Server.
Claude Code, ein Befehl:
claude mcp add --transport http opensourceai https://olud.ai/mcp.php \ --header "X-Api-Key: your-key" # ohne Schlüssel: claude mcp add --transport http opensourceai https://olud.ai/mcp.php # überprüfen, was registriert wurde: claude mcp list
Claude Desktop, claude_desktop_config.json:
{
"mcpServers": {
"opensourceai": {
"type": "http",
"url": "https://olud.ai/mcp.php",
"headers": { "X-Api-Key": "your-key" }
}
}
}Diese Datei befindet sich unter ~/Library/Application Support/Claude/claude_desktop_config.json auf macOS und %APPDATA%\Claude\claude_desktop_config.json auf Windows. Beenden Sie Claude Desktop und öffnen Sie es erneut, nachdem Sie es bearbeitet haben; es liest die Datei beim Start.
Wenn Claude Desktop den Server als fehlgeschlagen anzeigt oder ihn überhaupt nicht auflistet, akzeptiert Ihr Build nur lokale (stdio) Server. Verbinden Sie es mit mcp-remote, das Node installiert benötigt:
{
"mcpServers": {
"opensourceai": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://olud.ai/mcp.php",
"--header", "X-Api-Key:${OSAI_KEY}"],
"env": { "OSAI_KEY": "your-key" }
}
}
}Cursor, .cursor/mcp.json im Projekt (oder ~/.cursor/mcp.json für jedes Projekt):
{
"mcpServers": {
"opensourceai": {
"url": "https://olud.ai/mcp.php",
"headers": { "X-Api-Key": "your-key" }
}
}
}VS Code, .vscode/mcp.json im Arbeitsbereich:
{
"servers": {
"opensourceai": {
"type": "http",
"url": "https://olud.ai/mcp.php",
"headers": { "X-Api-Key": "${input:osaiKey}" }
}
},
"inputs": [
{ "id": "osaiKey", "type": "promptString",
"description": "olud.ai API-Schlüssel", "password": true }
]
}Ein Schlüssel in der URL wie ?key=your-key funktioniert ebenfalls, da der Server ihn liest. Bevorzuge den Header: Abfragezeichenfolgen landen in der Browserhistorie, Proxy-Protokollen und der Shell-Historie.
Mit curl prüfen, ob es läuft
Wenn ein Client sagt, dass ein Server nicht verfügbar ist, teste zuerst den Server selbst. Dieser Aufruf listet die Tools auf und kostet nichts: nur tools/call verringert dein Kontingent, daher sind initialize, tools/list und ping kostenlos. Das Neustarten deines Editors verbraucht nie den Tag.
curl -s -X POST https://olud.ai/mcp.php \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-key" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Eine gesunde Antwort ist HTTP 200 mit {"jsonrpc":"2.0","id":1,"result":{"tools":[ ... ]}} und den fünf Namen darin. Als Nächstes, verbrauche einen Aufruf:
curl -s -X POST https://olud.ai/mcp.php \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-key" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"search_open_source_ai",
"arguments":{"query":"text to speech","limit":5}}}'Ein erfolgreicher tools/call hat zwei Antwort-Header, die es wert sind, gelesen zu werden: X-RateLimit-Limit ist dein tägliches Kontingent, X-RateLimit-Remaining ist das, was nach diesem Aufruf übrig bleibt. Sie werden nur bei tools/call gesetzt.
Kürzester möglicher Lebenszeichencheck. Es antwortet {"jsonrpc":"2.0","id":0,"result":{}} und benötigt keinen Schlüssel:
curl -s -X POST https://olud.ai/mcp.php \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":0,"method":"ping"}'Die fünf Werkzeuge
Du rufst diese nicht namentlich auf. Du stellst eine Frage, der Client wählt das Tool. Die Namen sind wichtig, wenn du ein Protokoll liest oder den Aufruf selbst schreibst, und sie werden genau abgeglichen: search_open_source_ai funktioniert, Search_Open_Source_AI nicht.
| Werkzeug | Parameter | Grenzen und Standardwerte | Rückgaben |
|---|---|---|---|
| search_open_source_ai | query (string, erforderlich), limit (integer) | limit begrenzt auf 1 … dein Ergebnis-pro-Aufruf-Dach. Standard 10 oder dein Dach, wenn es niedriger ist | matches (insgesamt gefunden, nicht abgeschnitten), dann id, name, summary, stars, language, license, github, page, health score und label, recent trend |
| get_project | project (string, erforderlich) | Akzeptiert einen Slug (ollama-ollama), owner/repo, eine vollständige github.com-URL oder den genauen Projektnamen | Alles oben plus owner, forks, created, pushed, topics, die vollständige Gesundheitsanalyse, gewonnene Sterne und bis zu 5 aktuelle Releases |
| find_alternatives | product (string, erforderlich) | Name des kommerziellen Produkts. Abgleich anhand seines Slugs, dann anhand seines genauen Namens | product, page und die Alternativenliste, die selbst durch dein Ergebnis-pro-Aufruf-Dach begrenzt ist |
| list_models | provider (string), max_price_out (number), min_context (integer), free_only (boolean), limit (integer) | provider ist ein nicht groß-/kleinschreibungssensitiver Teilstring. max_price_out ist Dollar pro Million Ausgabetokens. min_context ist in Tokens. limit begrenzt auf 1 … dein Dach, Standard 15 oder dein Dach, wenn niedriger | matches, dann id, name, provider, context, price_per_million (input und output), modality, tool_calling und die leaderboard-URL |
| trending_projects | kind (string), limit (integer) | kind ist trending, emerging oder top_health. Alles andere fällt ohne Fehler auf trending zurück. Standard trending. limit begrenzt auf 1 … dein Dach, Standard 10 oder dein Dach, wenn niedriger | kind, die Projektkarten und die Generierungszeit des Index |
Fragen, die jedes Tool erreichen
- search_open_source_ai — "Finde mir eine Open-Source-OCR-Bibliothek, die ich lokal ausführen kann."
- get_project — "Wie gesund ist ollama/ollama gerade und wann wurde es zuletzt veröffentlicht?"
- find_alternatives — "Welches Open-Source-Tool könnte Notion für uns ersetzen?"
- list_models — "Welche Modelle haben mindestens 128k Kontext und kosten unter 1 $ pro Million Ausgabetokens?"
- trending_projects — "Welche Open-Source-AI-Projekte gewinnen diese Woche am schnellsten Sterne?" Bitte nach emerging fragen, um gesunde Projekte zu erhalten, die noch wenig bekannt sind, oder nach top_health für die am besten gewarteten.
Filter lassen das weg, was sie nicht beurteilen können. Mit max_price_out gesetzt, wird ein Modell, dessen Ausgabepreis wir nicht kennen, ausgeschlossen, anstatt geschätzt zu werden. Mit min_context gesetzt, zählt ein Modell ohne aufgezeichnetes Kontextfenster als null und wird ausgeschlossen. free_only behält Modelle, deren Stufe genau kostenlos ist.
Ein Limit über Ihrem Maximum ist kein Fehler: es wird stillschweigend begrenzt. Das veröffentlichte Schema sagt maximal 100, weil das die höchste Anzahl ist, die ein Plan erlaubt, nicht das, was Ihr Schlüssel erlaubt. Ein Limit, das keine Zahl ist, fällt auf den Standardwert zurück.
Volumen nach Plan
| Kein Schlüssel | Kostenlos | Entwickler | Pro | Org | |
|---|---|---|---|---|---|
| Anrufe pro Tag | 25 | 200 | 2,000 | 20,000 | 200,000 |
| Ergebnisse pro Anruf | 5 | 10 | 25 | 50 | 100 |
Zwei Obergrenzen, weil sie zwei verschiedene Dinge stoppen: Anfragen pro Tag begrenzen die Last, Ergebnisse pro Anfrage begrenzen, wie viel aus dem Katalog in einer Antwort herauskommt.
- MCP-Anfragen werden separat von REST-API-Anfragen gezählt. Gleicher Schlüssel, zwei Zähler. Ein Redakteur, der ein paar Fragen stellt, berührt nie Ihr API-Budget.
- Nur tools/call wird gezählt. initialize, tools/list und ping kosten nichts.
- Beide Zähler setzen sich um 00:00 UTC zurück.
- Ohne einen Schlüssel wird die Zählung pro IP-Adresse durchgeführt. Jeder hinter einer Büro-IP teilt sich die 25.
- Bei Free und ohne Schlüssel endet jede Antwort mit einer Notizzeile, die Ihre beiden Obergrenzen angibt. Dev-, Pro- und Org-Antworten tragen keine solche Zeile.
- Org ist der Plan, der im System als Geschäft bezeichnet wird. Fehlermeldungen drucken den internen Namen.
Wenn es nicht funktioniert
Schlüssel falsch eingegeben oder widerrufen. Jede Anfrage schlägt fehl mit:
Dieser API-Schlüssel ist unbekannt oder wurde widerrufen. Entfernen Sie ihn, um die kostenlose Stufe zu nutzen, oder erhalten Sie einen neuen unter https://olud.ai/account.html
Ein fehlerhafter Schlüssel fällt nicht stillschweigend auf die anonyme Erlaubnis zurück. Beheben Sie den Schlüssel oder entfernen Sie den X-Api-Key-Header vollständig, und starten Sie dann den Client neu, damit er die Konfiguration erneut liest.
Tägliches Limit erreicht. Mit einem Schlüssel, dann ohne:
Tägliches MCP-Kontingent erreicht (200 Anfragen/Tag im "freien" Plan). Setzt sich um 00:00 UTC zurück. Höhere Stufen: https://olud.ai/plans.html Anonymes Limit erreicht (25 Anfragen/Tag pro IP). Setzt sich um 00:00 UTC zurück. Ein kostenloser API-Schlüssel erhöht es auf 200/Tag — https://olud.ai/account.html
Nichts ist kaputt und nichts wird berechnet. Warten Sie auf 00:00 UTC oder steigen Sie auf. Wenn Sie keinen Schlüssel haben, bringt Sie ein kostenloser Schlüssel von 25 auf 200 Anfragen und von 5 auf 10 Ergebnisse pro Anfrage.
Toolname ist nicht eines der fünf:
Unbekanntes Tool "list_projects". Rufen Sie tools/list auf, um zu sehen, was verfügbar ist.
Ein erforderliches Argument fehlt. Jede Nachricht zeigt die Form, die sie möchte:
"query" fehlt. Beispiel: {"query": "text to speech"}
"project" fehlt. Beispiel: {"project": "ollama/ollama"}
"product" fehlt. Beispiel: {"product": "Midjourney"}Nichts gefunden. Beide Nachrichten sagen Ihnen, wohin Sie als Nächstes gehen sollen:
Kein Projekt für "ollamaa" gefunden. Versuchen Sie zuerst search_open_source_ai, um die genaue ID zu erhalten. Wir verfolgen "photoshop" noch nicht. Nächste Übereinstimmungen: <bis zu 8 Namen>. Vollständige Liste: https://olud.ai/alternatives-hub.html
Der Katalog wird gerade neu aufgebaut. Warten Sie eine Minute und fragen Sie erneut; dies sind die vier Formulierungen, eine pro Datensatz:
Der Katalog wird neu aufgebaut. Versuchen Sie es in einer Minute erneut. Diese Liste wird neu aufgebaut. Versuchen Sie es in einer Minute erneut. Der Modellkatalog ist momentan nicht verfügbar. Der Alternativenindex ist momentan nicht verfügbar.
Das Öffnen von https://olud.ai/mcp.php in einem Browser gibt HTTP 405 zurück. Das ist die richtige Antwort: der Endpunkt spricht JSON-RPC über POST, und die Spezifikation verlangt 405, wenn ein Server keinen GET-Stream anbietet. Der Body sagt Ihnen, was zu tun ist, und enthält die Konfiguration zum Kopieren. Er kommt in einer Zeile an; hier ist er aufgeteilt, um gelesen zu werden.
{
"server": "olud.ai MCP",
"version": "1.0.0",
"protocol": "2025-06-18",
"usage": "Dieser Endpunkt spricht MCP über JSON-RPC 2.0. POSTen Sie von einem MCP-Client aus.",
"config": { "mcpServers": { "opensourceai": { "url": "https://olud.ai/mcp.php" } } },
"tools": ["search_open_source_ai", "get_project", "find_alternatives",
"list_models", "trending_projects"],
"docs": "https://olud.ai/api.html"
}Transportebene-Verweigerungen. Diese vier tragen einen JSON-RPC-Fehlercode, und die ersten drei tragen auch einen HTTP-Fehlercode:
405 -32600 Verwenden Sie POST mit einem JSON-RPC 2.0-Body. (PUT, DELETE, HEAD…) 400 -32700 Parse-Fehler: der Body ist kein gültiges JSON. 400 -32600 JSON-RPC-Batching wird nicht unterstützt (in MCP 2025-06-18 entfernt). 200 -32601 Unbekannte Methode "tools/execute". 200 -32602 Fehlender Toolnamen in den Parametern.
Wenn Ihr Client sich über eine fehlende Sitzungs-ID beschwert, ignorieren Sie dies und überprüfen Sie den Transporttyp in Ihrer Konfiguration. Dieser Server speichert keine Sitzung, und es gibt keine Mcp-Session-Id, die zurückgesendet werden kann. Ein für stdio oder für SSE gegen diese URL konfigurierter Client schlägt vor dem ersten Aufruf fehl; der Typ ist http.
REST API
Authentifizierung und Schlüssel
Basis-URL: https://olud.ai/api/v1. Jeder Endpunkt ist ein GET. Der CORS-Header bewirbt POST, aber v1 hat keinen POST-Routen: Parameter werden immer aus der Abfragezeichenfolge gelesen.
Senden Sie Ihren Schlüssel im X-Api-Key-Header. Ein ?key= Abfrageparameter funktioniert auch, für einen Browser-Tab oder einen schnellen Test. Wenn beide vorhanden sind, hat der Header Vorrang. Nur /meta funktioniert ohne einen Schlüssel.
Beide Formen werden akzeptiert:
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ "https://olud.ai/api/v1/projects?limit=3" curl -s "https://olud.ai/api/v1/projects?limit=3&key=osk_YOUR_KEY"
Um einen Schlüssel zu erhalten: Melden Sie sich bei olud.ai an und öffnen Sie Ihre Kontoseite, Abschnitt Entwickler-API. Der Schlüssel wird bei Ihrem ersten Besuch im kostenlosen Plan erstellt und sieht aus wie osk_, gefolgt von 40 hexadezimalen Zeichen. Das Rotieren von der gleichen Seite löscht den alten Schlüssel sofort — der alte Wert gibt dann 403 invalid_key zurück.
| Header | Wert | Gesendet am |
|---|---|---|
| X-RateLimit-Limit | Ihr tägliches Limit, als Ganzzahl | Jede Anfrage, die den Schlüsselcheck bestanden hat |
| X-RateLimit-Remaining | Anfragen heute übrig, auf 0 gerundet | Jede Anfrage, die die Schlüsselprüfung bestanden hat, einschließlich der 429 |
| ETag | Quoted md5 der Build-Zeit des Projektgraphen | Jeder Endpunkt außer /meta |
| Access-Control-Allow-Origin | * | Jede Antwort, einschließlich OPTIONS (die 204 zurückgibt) |
Antwortenumschlag
Ein Erfolg ist immer HTTP 200 mit drei obersten Schlüsseln: ok ist true, data enthält die Nutzlast, meta enthält den Kontext. data ist ein Objekt bei Endpunkten mit einem einzelnen Datensatz und ein Array bei Listenendpunkten.
GET /api/v1/meta, wörtlich:
{"ok":true,"data":{"name":"olud.ai API","version":"v1","generated":"2026-07-27T07:45:15+00:00","counts":{"projects":10142},"endpoints":["/project/{id}","/projects","/emerging","/alternatives/{id}","/search?q=","/models"],"docs":"https://olud.ai/api/"},"meta":{"attribution":"Scores & indices computed by olud.ai (olud.ai). Kontextuelle Fakten aus öffentlichen Quellen: GitHub, Hugging Face, OpenRouter, Artificial Analysis, PyPI, NPM, Docker Hub."}}meta.attribution wird bei jeder Erfolgsantwort, bei jedem Endpunkt gesetzt und kann nicht deaktiviert werden. Der Rest von meta variiert je nach Endpunkt: generated, total, limit, offset, sort, freshness, points. Lesen Sie die Endpunktabschnitte, um herauszufinden, welche Felder Sie erhalten.
Ein Fehler enthält ok false, einen HTTP-Status ungleich 200 und error.code plus error.message. Es gibt kein meta-Objekt bei einem Fehler, also kein attribution-Feld. Testen Sie ok, bevor Sie data lesen — gehen Sie nicht davon aus, dass die Erfolgsform vorliegt.
GET /api/v1/projects ohne Schlüssel, wörtlich:
{"ok":false,"error":{"code":"missing_key","message":"Geben Sie Ihren API-Schlüssel über den X-Api-Key-Header (oder ?key=) an. Holen Sie sich einen unter https://olud.ai/api/"}}Senden Sie den ETag als If-None-Match zurück und Sie erhalten 304 mit einem leeren Körper, wenn der Graph nicht neu aufgebaut wurde. Der Graph wird einmal jeden Morgen neu aufgebaut, sodass häufigeres Abfragen als das den ganzen Tag 304 zurückgibt.
Endpunkte: Meta und Projekte
GET /meta
Graphstatus. Der einzige Endpunkt ohne Schlüssel und der einzige, der nicht gegen Ihr Kontingent zählt. Gibt den API-Namen und die Version, generated (UTC-Zeitstempel des letzten Graphenaufbaus), counts.projects, eine Liste von Endpunkten und die URL der Dokumentation zurück. Keine Parameter. Wenn die Graphdateien nicht lesbar sind, ist counts null und der Aufruf gibt trotzdem 200 zurück — verwenden Sie es als Gesundheitscheck und um zu entscheiden, ob ein erneutes Abrufen sinnvoll ist. Es sendet keinen ETag und keine Rate-Limit-Header.
curl -s https://olud.ai/api/v1/meta
GET /project/{id}
Ein Projekt, vollständiger Datensatz. Dies ist die zusammengeführte Ansicht: GitHub-Fakten, unsere Wartungsbewertung, Sternen-Velocity, Veröffentlichungen, Adoptions-Puls.
- Identität: id, name, owner, url, page (Pfad der Projektseite auf der Website), desc.
- GitHub-Fakten zum letzten Build: Sterne, Forks, lang, Lizenz, Themen, erstellt, gepusht.
- health: Punktzahl von 100, Label, warum, plus die vier Komponenten, aus denen sie besteht — Aktivität (max 30), Momentum (max 20), Community (max 30), Wartung (max 20) — Gewichte v2 seit 29. Juli 2026 — und geprüft. Labels folgen der Punktzahl: 85+ Thriving, 70+ Healthy, 50+ Maintained, 30+ Slowing down, unter 30 At risk. Ein Projekt ohne Commit in vier Wochen hat seine Punktzahl auf 45 begrenzt, sodass die Komponenten mehr als die Punktzahl addieren können. Nicht jedes Projekt wird bewertet; testen Sie auf das Feld.
- velocity: stars_1d und stars_7d, aus unserer eigenen täglichen Sternhistorie.
- releases: tag, datum, level, url — die aktuellsten zuerst.
- tool: slug, cat, pulse, docker_pulls, npm_month, pip_month, hn_hits, bsky_week, compare_pages. Nur für Projekte, die mit einem verfolgten Tool übereinstimmen, vorhanden.
- rank, trend (stabil, ruhig oder beschleunigend) und Signale (stars_accel, has_page).
| Parameter | Typ | Standard | Verhalten |
|---|---|---|---|
| id | Pfadsegment, erforderlich | keine | Kleinbuchstaben. Wird in drei Schritten aufgelöst: exakter slug, dann das owner/name-Index, dann owner-name. Kein Segment gibt 400 missing_id zurück; kein Treffer gibt 404 not_found mit einem Hinweis auf /search zurück. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ https://olud.ai/api/v1/project/ollama-ollama
GET /projects
Filter, sortieren und blättern Sie im Katalog. Filter werden zuerst angewendet, dann die Sortierung, dann Offset und Limit.
| Parameter | Typ / Grenzen | Standard | Verhalten |
|---|---|---|---|
| lang | string | kein Filter | Exakte Übereinstimmung mit der Projektsprache, nicht groß-/kleinschreibungsempfindlich. lang=rust behält nur Rust bei. |
| Lizenz | string | kein Filter | Teilzeichenfolgenübereinstimmung mit der Lizenz-ID, nicht groß-/kleinschreibungsempfindlich. license=gpl behält GPL-2.0 und AGPL-3.0 bei. |
| vertikal | string | kein Filter | Exakte Übereinstimmung, nicht groß-/kleinschreibungsempfindlich. Werte, die im Diagramm vorhanden sind: robotik, sicherheit, finanz, wissenschaft, gesundheit, bildung, recht. Die meisten Projekte haben keine, und sie verschwinden alle, wenn Sie dies einstellen. |
| health_min | ganzzahl | kein Filter | Beibehaltung von Projekten, deren health.score größer oder gleich dem Wert ist. Nicht bewertete Projekte zählen als 0 und fallen heraus. Ein nicht-numerischer Wert wird zu 0, was nichts filtert. |
| sortieren | sterne, gesundheit, momentum oder aktuell | sterne | Immer absteigend. momentum liest velocity.stars_7d, aktuell liest das letzte Push-Datum. Ein unbekannter Wert wird nach Sternen sortiert, aber unverändert in meta.sort zurückgegeben — überprüfen Sie meta.sort, wenn die Reihenfolge Sie überrascht. |
| limit | ganzzahl 1-100 | 25 | Außerhalb des Bereichs liegende Werte werden auf die Grenzen beschränkt, nicht-numerische Werte fallen auf 25 zurück. Es wird kein Fehler ausgelöst, sodass limit=500 Ihnen stillschweigend 100 gibt. |
| offset | ganzzahl 0-100000 | 0 | Wird auf die gleiche Weise beschränkt. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ "https://olud.ai/api/v1/projects?lang=python&license=apache&sort=health&health_min=70&limit=10"
Daten sind ein Array von kompakten Karten: id, name, url, desc, sterne, lang, lizenz, gesundheit (nur der Score), momentum (stars_7d), trend, vertikal. Felder ohne Wert sind vorhanden und null. Für die Komponenten, Veröffentlichungen und Adoptionszahlen rufen Sie /project/{id} auf. meta gibt total (Übereinstimmungen nach Filterung, vor Paging), limit, offset, sort und generiert an.
Endpunkte: Suche, Neuheiten, Alternativen
GET /search
Durchsucht Projekte nach Name, Beschreibung und Themen. Es durchsucht keine Modelle oder Hugging Face-Reihen — verwenden Sie /models und /hf dafür.
| Parameter | Typ / Grenzen | Standard | Verhalten |
|---|---|---|---|
| q | string, erforderlich | keine | Getrimmt und in Kleinbuchstaben. Leer oder nur Leerzeichen gibt 400 missing_query zurück. |
| limit | ganzzahl 1-50 | 15 | Auf die Grenzen beschränkt; nicht-numerische Werte fallen auf 15 zurück. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ "https://olud.ai/api/v1/search?q=ocr&limit=5"
Bewertung, damit Sie die Reihenfolge vorhersagen können: exakte Namensübereinstimmung 100, Name beginnt mit q 60, Name enthält q 40, Beschreibung enthält q 15, und +20, wenn q genau einem der Themen des Projekts entspricht. Gleichstände werden nach Sternen aufgelöst. Alles, was 0 Punkte hat, wird ausgeschlossen. Die Übereinstimmung erfolgt durch einfache Teilzeichenfolgen — kein Stemming, keine Tippfehler-Toleranz. Karten haben die gleiche Form wie /projects. meta gibt total (alle Übereinstimmungen, nicht die Seite) und q als normalisiert an.
GET /emerging
Der tägliche Entdeckungsindex: junge Repositories mit nachhaltigem Wachstum und, wo wir sie bewerten können, guter Gesundheit. Rangiert nach unserem Discovery Score. Karten tragen zwei zusätzliche Felder: signals und detected, das Datum, an dem das Projekt erstmals in den Index aufgenommen wurde (null, wenn unbekannt).
| Parameter | Typ / Grenzen | Standard | Verhalten |
|---|---|---|---|
| limit | ganzzahl 1-100 | 25 | Beschränkt. Sie können weniger Zeilen erhalten, als Sie angefordert haben: IDs, die nicht mehr im Projektdiagramm vorhanden sind, werden übersprungen. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ "https://olud.ai/api/v1/emerging?limit=10"
Frische hängt vom Plan ab, und meta sagt, welchen Sie erhalten haben. Pro und Business lesen den Index von heute Morgen und erhalten meta.freshness "realtime". Free und Dev lesen den Snapshot von gestern und erhalten "previous-day" plus eine meta.note. Zwei Konsequenzen, die es wert sind, bekannt zu sein: Bei Free und Dev ist meta.criteria null, da der Kriterien-Text nur mit dem aktuellen Index gespeichert wird; und wenn die Snapshot-Datei von gestern fehlt, erhalten Free und Dev den aktuellen Index, während meta.freshness weiterhin "previous-day" anzeigt.
GET /alternatives/{product}
Open-Source-Alternativen zu einem kommerziellen Produkt. data gibt name, domain, desc, page, cat und ein alternatives-Array zurück, dessen Einträge name, repo, site, lizenz und desc enthalten. repo kann ein leerer String sein, wenn das Projekt kein GitHub-Repository hat. meta gibt generiert an.
| Parameter | Typ | Standard | Verhalten |
|---|---|---|---|
| Produkt | Pfadsegment, erforderlich | keine | Kleinbuchstaben. Exakter Produkt-Schlüssel zuerst; falls nicht vorhanden, das erste Produkt, dessen Schlüssel oder Name deinen String enthält, in der Dateireihenfolge. Kein Segment gibt 400 missing_id zurück; kein Treffer gibt 404 not_found zurück. Übergebe den exakten Slug — den in der URL der /alternatives/<slug>.html-Seite — wenn du ein spezifisches Produkt benötigst, da lose Übereinstimmung den ersten Treffer nimmt, nicht den besten. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ https://olud.ai/api/v1/alternatives/notion
Endpunkte: Modelle, hf, Verlauf
GET /models
Modellkatalog, erstellt von OpenRouter. Jede Zeile: id, name, provider, tier, ctx (Kontextfenster in Tokens), price_in und price_out (US-Dollar pro Million Tokens, auf zwei Dezimalstellen gerundet, 0, wenn die Quelle keinen Preis angibt), modality (zum Beispiel text->text oder text+image+file->text), tools (boolean) und rank. Felder ohne Wert werden aus der Zeile entfernt, also überprüfe auf Vorhandensein, anstatt anzunehmen, dass price_in existiert. meta gibt total, limit, offset, generated und source an.
| Parameter | Typ / Grenzen | Standard | Verhalten |
|---|---|---|---|
| provider | string | kein Filter | Teilzeichenfolgenübereinstimmung, nicht groß-/kleinschreibungsempfindlich. provider=mistral entspricht "Mistral AI". |
| tier | kostenlos oder bezahlt | kein Filter | Exakte Übereinstimmung, nicht groß-/kleinschreibungsempfindlich auf deinem Input. |
| limit | integer 1-200 | 50 | An die Grenzen angepasst; nicht-numerische Werte fallen auf 50 zurück. |
| offset | ganzzahl 0-100000 | 0 | Angewendet auf die zusammengeführte Liste. Offene Gewichtzeilen kommen zuerst, dann proprietäre, jeder Block in Rangfolge. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ "https://olud.ai/api/v1/models?tier=free&provider=mistral&limit=20"
GET /hf
Hugging Face: am häufigsten heruntergeladen und im Trend. Keine Parameter. data hat drei Arrays — top_llm (Textgenerierungsmodelle nach 30-Tage-Downloads), top (alle Aufgaben, auf 30 Zeilen durch diesen Endpunkt begrenzt) und trending (heutige Aufsteiger). Jede Zeile: id, org, name, task, downloads (rollierende 30 Tage), likes, license, gated, created, updated, trend (Anstieg der Likes bei trendenden Zeilen, null anderswo). meta gibt generated und source an.
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ https://olud.ai/api/v1/hf
GET /history/{slug}
Tägliche Serie für ein Projekt: Sterne, Gesundheit und 7-Tage-Geschwindigkeit. Pro- und Business-Keys nur — der Business-Plan ist der, der als Org verkauft wird. Jeder andere Plan erhält 403 pro_required. data gibt slug, days (Daten im Format YYYY-MM-DD, älteste zuerst) und series mit drei Arrays, stars, health und velocity_7d, indexweise ausgerichtet mit days. Einzelne Einträge können null sein, wenn der Wert eines Tages fehlte. meta gibt points und window an.
| Parameter | Typ | Standard | Verhalten |
|---|---|---|---|
| slug | Pfadsegment, erforderlich | keine | Kleinbuchstaben, und muss mit ^[a-z0-9][a-z0-9._-]*$ übereinstimmen — die gleiche id wie /project/{id}. Alles andere gibt 400 bad_slug zurück. Ein gültiger slug, für den noch nichts aufgezeichnet wurde, gibt 404 not_found zurück. |
curl -s -H "X-Api-Key: osk_YOUR_KEY" \ https://olud.ai/api/v1/history/ollama-ollama
Tägliche Quoten
Anfragen werden pro Schlüssel, pro UTC-Tag gezählt. Der Zähler wird um 00:00 UTC zurückgesetzt. Es gibt keine pro-Sekunde oder pro-Minute-Beschränkung im Code.
| Plan auf dem Schlüssel | Anfragen / Tag | Öffentlicher Name | Was es ändert |
|---|---|---|---|
| kostenlos | 500 | Kostenlos | Alles außer /history. /emerging dient dem Index des vorherigen Tages. |
| dev | 5000 | Entwickler | Gleicher Zugriff wie Free, höhere Obergrenze. |
| pro | 50000 | Pro | /history öffnet. /emerging dient dem Index von heute Morgen. |
| business | 500000 | Org | Gleicher Zugriff wie Pro, höhere Obergrenze. |
Was zählt: jeder Endpunkt außer /meta, eine Einheit pro Anfrage. Der Zähler wird direkt nach der Überprüfung des Schlüssels und vor allem anderen erhöht, sodass ein 304, ein 404 not_found, ein 400 missing_query und ein 503 graph_unavailable jeweils eine Einheit kosten. Nur 401 missing_key und 403 invalid_key kosten nichts, da es keinen gültigen Schlüssel gibt, den man belasten könnte.
Ein Quotenfeld, das auf deinem Schlüssel festgelegt ist, überschreibt den Planstandard. X-RateLimit-Limit ist die Autorität über deine Obergrenze, nicht die Tabelle oben.
Über der Obergrenze gibt jede Anfrage 429 quota_exceeded zurück, bis der Reset erfolgt. Die abgelehnte Anfrage wird nicht gezählt, es wird nichts in die Warteschlange gestellt und nichts wird berechnet. Kein Retry-After-Header wird gesendet — der Reset erfolgt um 00:00 UTC.
So sieht eine abgelehnte Anfrage mit einem kostenlosen Schlüssel aus:
HTTP/2 429
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
{"ok":false,"error":{"code":"quota_exceeded","message":"Tägliches Kontingent erreicht (500 Anfragen/Tag im \"kostenlosen\" Plan). Setzt sich um 00:00 UTC zurück."}}Fehlercodes
Jeder Fehler gibt error.code als stabilen String zurück. Branchen Sie darauf, nicht auf den Nachrichtentext, der Slugs und Plan-Namen enthält und sich mit der Anfrage ändert.
| HTTP | code | Trigger | Was zu tun ist |
|---|---|---|---|
| 401 | missing_key | Kein X-Api-Key-Header und kein ?key=. Auch das, was Sie für einen unbekannten Pfad erhalten, wenn kein Schlüssel gesendet wird, da die Schlüsselüberprüfung vor dem Routing erfolgt. | Senden Sie den Schlüssel. Ein 401 auf einem Pfad, von dem Sie sicher sind, dass er existiert, ist ein fehlender Header, nicht ein falscher Pfad. |
| 403 | invalid_key | Der Schlüssel ist nicht im Speicher oder sein aktives Flag ist falsch. Das Rotieren Ihres Schlüssels löscht den vorherigen. | Lesen Sie den aktuellen Schlüssel von Ihrer Kontoseite und aktualisieren Sie den Aufrufer. Rotation bricht jede bereitgestellte Kopie des alten Schlüssels auf einmal. |
| 403 | pro_required | /history wurde mit einem kostenlosen oder Dev-Schlüssel aufgerufen. | Lesen Sie die heutigen Werte von /project/{id} (Gesundheit, Geschwindigkeit) oder wechseln Sie zu Pro. |
| 429 | quota_exceeded | Der tägliche Zähler hat Ihre Obergrenze erreicht. | Hören Sie auf, bis 00:00 UTC zu rufen, oder erhöhen Sie den Plan. Lesen Sie X-RateLimit-Limit, um Ihre tatsächliche Obergrenze zu bestätigen. |
| 400 | missing_id | /project oder /alternatives wurde ohne Pfadsegment aufgerufen. | Fügen Sie das Segment hinzu. /v1/project allein ist keine Auflistung — verwenden Sie /v1/projects. |
| 400 | missing_query | /search mit leerem oder nur Leerzeichen q. | Senden Sie ein nicht leeres q. Beachten Sie, dass die Anfrage trotzdem gezählt wurde. |
| 400 | bad_slug | /history slug leer oder enthält ein Zeichen außerhalb von ^[a-z0-9][a-z0-9._-]*$. | Geben Sie die ID genau so an, wie sie von /projects oder /search zurückgegeben wurde. |
| 404 | not_found | Unbekannte Projekt-ID, keine Alternativen für dieses Produkt verfolgt oder keine Historie für diesen Slug gespeichert. | Für ein Projekt, versuchen Sie es erneut über /search?q=. Für die Historie könnte das Projekt zu kürzlich in die Verfolgung eingetreten sein, um Punkte zu haben. |
| 404 | unknown_endpoint | Gültiger Schlüssel, Pfad nicht im Router. | Überprüfen Sie die Schreibweise. /meta listet sechs Endpunkte auf und lässt /hf und /history aus, die beide existieren. |
| 503 | graph_unavailable | Eine Graphdatei fehlt oder ist nicht lesbar, was passiert, während der morgendliche Build sie schreibt. | Versuchen Sie es in einer Minute erneut. Ihr Schlüssel ist in Ordnung; rotieren Sie ihn nicht. |
| 503 | nicht_bereit | /hf vor dem morgendlichen Hugging Face-Scan hat seine Datei produziert. | Versuchen Sie es später am Tag erneut. Andere Endpunkte sind nicht betroffen. |
| 304 | kein Körper | If-None-Match stimmte mit dem aktuellen ETag überein. | Dienen Sie Ihrer zwischengespeicherten Kopie. Denken Sie daran, dass dies eine Anfrage aus Ihrem Kontingent verbraucht hat. |
Wiederholungsrichtlinie, die dem Code entspricht: Wiederholen bei 503 nach einer Minute und bei 429 nur nach dem UTC-Reset. Wiederholen Sie niemals einen 400, 403 oder 404 unverändert — die Antwort wird sich nicht ändern und jeder Versuch kostet eine Anfrage.
Webhooks
Einen Webhook erstellen
Ein Webhook ist ein signiertes POST an Ihren Endpunkt pro Ereignis. Sie wählen die Ereignisse, die Repositories und die Form des Körpers. Webhooks benötigen einen kostenpflichtigen Plan: Bei einem kostenlosen Schlüssel antwortet die Erstellung mit 403 paid_feature und die Kontoseite zeigt ein gesperrtes Panel anstelle des Formulars.
| Plan, der von der API gemeldet wurde | Webhooks erlaubt |
|---|---|
| kostenlos | 0 |
| dev | 3 |
| pro | 10 |
| business | 50 |
Ein Planname, den wir nicht erkennen, fällt auf 1 zurück. Sobald Sie bei Ihrer Anzahl sind, antwortet die Erstellung mit 429 limit_reached — löschen Sie einen oder ändern Sie den Plan.
Von Ihrem Konto
- Melden Sie sich an und öffnen Sie /account.html. Die Webhooks-Karte erscheint, sobald Ihr API-Schlüssel geladen ist, und bleibt bis dahin verborgen.
- Fügen Sie Ihren Endpunkt im URL-Feld ein. Die Seite akzeptiert nichts, was nicht mit https:// beginnt.
- Wählen Sie die Ereignisse aus. release und health sind für Sie ausgewählt; license und new_project sind es nicht.
- Lassen Sie das Feld für Repos leer, um alles zu erhalten, oder geben Sie Einträge im Format owner/name getrennt durch Kommas ein.
- Wählen Sie das Ziel im Auswahlfeld: Ihren eigenen Endpunkt (raw signiertes JSON), Slack oder Discord.
- Drücken Sie Erstellen. Das Geheimnis erscheint einmal in einem grünen Feld. Kopieren Sie es, bevor Sie die Seite verlassen — nichts zeigt es wieder an.
- Jede Zeile des Webhooks trägt dann einen Send test ping-Button und einen Löschen-Link. Das Löschen stoppt die Lieferungen sofort.
Von der API — erstellen. Ihr API-Schlüssel ist der in Ihrem Konto, gesendet als X-Api-Key (oder ?key=).
curl -sS -X POST https://olud.ai/api/webhooks.php \
-H "X-Api-Key: $OSAI_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.example/osai-hook",
"events": ["release", "health", "license"],
"repos": ["acme/inference-server", "acme/tiny-router"],
"format": "json"
}'Der Datenblock der Antwort. Jede Antwort enthält auch einen Meta-Block mit unserer Attribution. Das Geheimnis ist hier und sonst nirgendwo.
{
"id": "whk_9b41c7e2f0a5d3861c4e",
"url": "https://your-app.example/osai-hook",
"events": ["release", "health", "license"],
"repos": ["acme/inference-server", "acme/tiny-router"],
"secret": "whs_7d2a19f4c6b03e58a1d7f492c0b6e35847ac91d2e6f0b8a3",
"note": "Speichern Sie dieses Geheimnis jetzt — es wird nur einmal angezeigt. Überprüfen Sie jede Lieferung: X-OSAI-Signature == \"sha256=\" + HMAC_SHA256(raw_body, secret). Testen Sie es: POST {\"ping\":\"whk_9b41c7e2f0a5d3861c4e\"}."
}Was die URL erfüllen muss
- Schema https. http wird abgelehnt.
- Ein Host muss vorhanden sein.
- Wenn Sie einen Port angeben, muss er 443 sein. https://your-app.example:8443/hook wird abgelehnt.
- Der Host kann nicht localhost sein und darf nicht mit .local oder .internal enden.
- Wir lösen den Host auf. Wenn eine Adresse, die zurückgegeben wird, in einem privaten oder reservierten Bereich liegt, wird die URL abgelehnt.
- Wir rufen Ihren Endpunkt während der Erstellung nicht auf. Ein Host, der nicht aufgelöst werden kann, besteht diesen Test und schlägt später bei der Lieferung fehl. Senden Sie einen Test-Ping, um es herauszufinden.
- Eine schlechte URL antwortet mit 400 bad_url.
Was Repos akzeptiert
- Der Standardwert ist ["*"] — jedes Repository, das wir verfolgen.
- Einträge werden beschnitten und in Kleinbuchstaben umgewandelt, sodass die Übereinstimmung nicht groß-/kleinschreibungssensitiv ist.
- Ein Eintrag muss wie owner/name aussehen: owner beginnt mit einem Buchstaben oder einer Ziffer, gefolgt von Buchstaben, Ziffern, Punkt, Unterstrich, Bindestrich.
- Einträge, die nicht übereinstimmen, werden ohne ein Wort verworfen. Wenn nichts übrig bleibt, erhalten Sie 400 bad_repos.
- "*" überall in der Liste ersetzt die gesamte Liste. ["acme/one", "*"] wird als ["*"] gespeichert.
- Mehr als 100 Einträge antworten mit 400 too_many_repos. Verwenden Sie "*" ab diesem Punkt.
Die vier Ereignisse
Jedes Ereignis trägt ein Repository. Ein Ereignis ist ein POST — Ereignisse werden niemals zusammengefasst. Der Name befindet sich im X-OSAI-Event-Header und im Ereignisfeld des Körpers.
| Ereignis | Wird ausgelöst, wenn | Schlüssel innerhalb der Daten |
|---|---|---|
| Gesundheit | das Gesundheitslabel eines Repositories sich ändert | von, zu, Sterne, Seite |
| Veröffentlichung | ein neuer Release-Tag für ein Repository erscheint | Tag, Name, URL |
| Lizenz | die Lizenz, die wir für ein Repository halten, sich ändert | von, zu |
| neues_projekt | ein Repository betritt das Verzeichnis | Sterne, Seite |
Gesundheit
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "health",
"repo": "acme/inference-server",
"data": {
"from": "Gedeihend",
"to": "Verlangsamt",
"stars": 58120,
"page": "https://olud.ai/project/acme-inference-server.html"
},
"sent_at": "2026-07-27T05:41:12+00:00"
}von und zu sind Labels, keine Zahlen. Die sechs Labels, die wir veröffentlichen: Gedeihend, Gesund, Wartungsfähig, Verlangsamt, Gefährdet, Archiviert. Sterne ist die Anzahl der Sterne, die wir für das Repository halten. Kein Ereignis wird ausgelöst, wenn ein Repository zum ersten Mal ein Label erhält — eine Änderung benötigt einen vorherigen Wert zum Vergleichen.
Veröffentlichung
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "release",
"repo": "acme/inference-server",
"data": {
"tag": "v0.6.2",
"name": "Acme Inference Server",
"url": "https://github.com/acme/inference-server/releases"
},
"sent_at": "2026-07-27T05:41:12+00:00"
}Tag ist der Git-Tag. Name ist der Anzeigename des Projekts in unserem Verzeichnis, nicht der Titel des Releases. URL verweist immer auf die Releases-Seite des Repositories, niemals auf ein spezifisches Release — baue die Tag-URL selbst, wenn du sie benötigst.
Lizenz
von und zu sind die Lizenzstrings, die wir halten. Dieses Ereignis hat keinen Seiten-Schlüssel.
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "license",
"repo": "acme/inference-server",
"data": {
"from": "Apache-2.0",
"to": "BSL-1.1"
},
"sent_at": "2026-07-27T05:41:12+00:00"
}neues_projekt
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "new_project",
"repo": "acme/tiny-router",
"data": {
"stars": 1840,
"page": "https://olud.ai/project/acme-tiny-router.html"
},
"sent_at": "2026-07-27T05:41:12+00:00"
}Höchstens 25 new_project-Ereignisse pro Durchlauf, höchste Sternzahlen zuerst. Bei einem ersten Durchlauf oder wenn mehr als 200 Repositories gleichzeitig erscheinen, werden sie aufgezeichnet und keine werden gesendet — dieser Schutz verhindert, dass ein erneutes Importieren dich überflutet.
Body und Header
Im Format JSON hat der Body fünf Schlüssel, in dieser Reihenfolge. Nichts anderes wird hinzugefügt.
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "release",
"repo": "acme/inference-server",
"data": { },
"sent_at": "2026-07-27T05:41:12+00:00"
}webhook_id ist die ID, die du erstellt hast: whk_ plus 20 hexadezimale Zeichen. repo ist der Kleinbuchstaben-Besitzer/Name und ist nur bei einem Test-Ping null. data ist ein Objekt, das leer ist für ein Ereignis, das keine Felder trägt. sent_at ist UTC, ISO 8601 mit einem Offset.
| Header | Wert |
|---|---|
| Content-Type | application/json |
| User-Agent | olud.ai-Webhooks/1.0 |
| X-OSAI-Event | health, release, license, new_project oder ping |
| X-OSAI-Delivery | 16 hexadezimale Zeichen, frisch für jeden POST |
| X-OSAI-Signature | sha256= gefolgt von der HMAC-SHA256 des Bodys |
Diese fünf sind das gesamte Set. X-OSAI-Delivery wird nicht auf unserer Seite gespeichert — verwende es, um ein Duplikat in deinem eigenen Protokoll zu erkennen.
Ein Test-Ping, gesendet durch POST {"ping":"whk_…"}. Dieselben Header, dieselbe Signatur, X-OSAI-Event: ping.
{
"webhook_id": "whk_9b41c7e2f0a5d3861c4e",
"event": "ping",
"repo": null,
"data": {
"message": "Es funktioniert. Echte Ereignisse kommen nach jedem Morgenscan an."
},
"sent_at": "2026-07-27T05:41:12+00:00"
}Die Signatur überprüfen
Berechne die HMAC-SHA256 des rohen Bodys mit deinem Geheimnis neu, präge es mit sha256= vor und vergleiche es mit X-OSAI-Signature. Das Geheimnis ist der whs_ String aus der Erstellungsantwort: whs_ plus 48 hexadezimale Zeichen.
PHP
<?php
$raw = file_get_contents('php://input'); // rohe Bytes, vor jeder Analyse
$sent = $_SERVER['HTTP_X_OSAI_SIGNATURE'] ?? '';
$expect = 'sha256=' . hash_hmac('sha256', $raw, $SECRET);
if (!hash_equals($expect, $sent)) { // konstante Zeit
http_response_code(401);
exit;
}
$event = json_decode($raw, true); // nur nach der Überprüfung parsen
http_response_code(200);Node, mit Express
const crypto = require('crypto');
const express = require('express');
const app = express();
// express.raw behält die Bytes. express.json() würde sie zerstören.
app.post('/osai-hook', express.raw({ type: 'application/json' }), (req, res) => {
const sent = req.get('X-OSAI-Signature') || '';
const expect = 'sha256=' + crypto.createHmac('sha256', SECRET)
.update(req.body).digest('hex');
// timingSafeEqual wirft einen RangeError bei Puffern unterschiedlicher Länge,
// also überprüfe zuerst die Länge und vergleiche dann in konstanter Zeit.
const a = Buffer.from(sent), b = Buffer.from(expect);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString('utf8'));
res.sendStatus(200);
});Python, mit Flask
import hmac, hashlib, json
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/osai-hook")
def osai_hook():
raw = request.get_data() # Bytes, vor jeder Analyse
expect = "sha256=" + hmac.new(SECRET.encode(), raw, hashlib.sha256).hexdigest()
sent = request.headers.get("X-OSAI-Signature", "")
if not hmac.compare_digest(expect, sent): # konstante Zeit
abort(401)
event = json.loads(raw)
return "", 200Vergleichen Sie mit hash_equals, crypto.timingSafeEqual oder hmac.compare_digest. Niemals mit == oder ===. Ein einfacher String-Vergleich stoppt beim ersten Byte, das sich unterscheidet, sodass die benötigte Zeit einem Angreifer verrät, wie viele führende Bytes sie richtig haben. Wiederholen Sie die Messung und sie rekonstruieren die Signatur Byte für Byte, um dann gefälschte Ereignisse zu posten. Die drei oben genannten Funktionen lesen jedes Byte, unabhängig von der Eingabe.
- Hashen Sie die rohen Bytes, bevor Sie sie parsen. Ein Körper, den ein Framework geparst und neu serialisiert hat, wird zu etwas anderem gehasht, und jede Lieferung wird ungültig aussehen.
- Das JSON-Format entkommt nicht-ASCII-Zeichen als \uXXXX. Eine erneute Serialisierung verliert das ebenfalls.
- Ein fehlender Header kommt als leerer String an. Alle drei Beispiele lehnen ihn ab, anstatt abzustürzen.
- Das Geheimnis wird einmal bei der Erstellung angezeigt. Wenn Sie es verlieren, löschen Sie den Webhook und erstellen Sie einen neuen — Sie erhalten eine neue ID und ein neues Geheimnis.
- Halten Sie ein Geheimnis pro Webhook. Zwei Webhooks teilen sich niemals eines.
json, slack, discord
Das Format wird bei der Erstellung gewählt und standardmäßig auf JSON gesetzt. Es gibt keinen Update-Endpunkt: Um es zu ändern, löschen Sie den Webhook und erstellen Sie einen neuen. GET berichtet das Format jedes Webhooks; die Antwort bei der Erstellung gibt es nicht wieder. Ein Wert außerhalb der drei Antworten 400 bad_format.
| Format | Was wir posten | URL zum Einfügen |
|---|---|---|
| JSON | Die obige Payload, unverändert | Ihr eigener Endpunkt |
| Slack | Text, plus einen mrkdwn-Abschnitt Block | Eine Slack Incoming-Webhook-URL |
| Discord | Ein Embed: Titel, URL, Beschreibung, Farbe, Fußzeile | Eine Discord-Kanal-Webhook-URL |
Slack
Ein Release-Ereignis, gepostet an Slack
{
"text": "🚀 acme/inference-server veröffentlicht v0.6.2 — Acme Inference Server",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "🚀 *<https://github.com/acme/inference-server/releases|acme/inference-server veröffentlicht v0.6.2>*\nAcme Inference Server"
}
}
]
}Holen Sie die URL von Slack: Fügen Sie eine App zum Arbeitsbereich hinzu, aktivieren Sie Incoming Webhooks, fügen Sie einen für den gewünschten Kanal hinzu, kopieren Sie die https://hooks.slack.com/services/… URL und fügen Sie sie in das URL-Feld ein. Text ist immer ausgefüllt — es ist das, was Slack in der Benachrichtigung und in Clients anzeigt, die keine Blöcke rendern.
Discord
Ein Lizenzereignis, gepostet an Discord
{
"embeds": [
{
"title": "🔑 acme/inference-server hat die Lizenz geändert",
"url": "https://github.com/acme/inference-server",
"description": "Apache-2.0 → BSL-1.1",
"color": 14427686,
"footer": { "text": "olud.ai" }
}
]
}Holen Sie die URL von Discord: Kanaleinstellungen, Integrationen, Webhooks, Neuer Webhook, Webhook-URL kopieren — https://discord.com/api/webhooks/… — und fügen Sie sie in das URL-Feld ein. Farbe ist eine dezimale Ganzzahl: 14427686 (#DC2626) für Lizenz, 6514417 (#6366F1) für Release, new_project und ping.
Beide Hosts bestehen die URL-Prüfung. Wenn ein Lizenzereignis keine Seite hat, fällt der Link zurück auf https://github.com/owner/name; health und new_project verlinken zur Projektseite auf olud.ai; release verlinkt zur Releases-Seite des Repositories.
Lieferung, Fehler, Deaktivierung
Lieferungen laufen über den Alert-Pass, send-alerts.php — die gleiche Erkennung, die die Mitglieds-E-Mails produziert. Der Versand erfolgt direkt nach der Erkennung im selben Prozess. Es gibt keinen separaten Zeitplan und keine Warteschlange. Die API beschreibt die Frequenz als "täglich, nach dem morgendlichen Scan".
- Ein POST pro Ereignis, pro passendem Webhook. Ein Webhook empfängt ein Ereignis, wenn der Ereignisname in seiner Ereignisliste steht und wenn das Repository in seiner Repos-Liste oder Repos ist ["*"].
- Ein Erfolg ist HTTP 200 bis 299, innerhalb des 6-Sekunden-Timeouts. Ein 4xx, ein 5xx, ein Timeout, ein DNS- oder TLS-Fehler zählen alle als Fehler.
- Ein Erfolg setzt fails auf 0 zurück und fügt 1 zu delivered hinzu.
- Ein Fehler fügt 1 zu fails hinzu. Es gibt keinen Retry. Das Ereignis wird nicht erneut gesendet — die nächste Lieferung ist die nächste Änderung, die wir erkennen.
- Bei 10 aufeinanderfolgenden Fehlern wird der Webhook deaktiviert, mit dem UTC-Zeitstempel dieses Moments versehen, und die verbleibenden Ereignisse dieser Ausführung werden für ihn übersprungen.
- Ein deaktivierter Webhook bleibt in Ihrer Liste, als deaktiviert markiert. Es gibt keinen Aufruf, um ihn wieder zu aktivieren: Löschen Sie ihn und erstellen Sie einen neuen, mit einer neuen ID und einem neuen Geheimnis.
Den Status lesen
curl -sS https://olud.ai/api/webhooks.php -H "X-Api-Key: $OSAI_KEY"
Die Antwort, einschließlich Meta
{
"ok": true,
"data": [
{
"id": "whk_9b41c7e2f0a5d3861c4e",
"url": "https://your-app.example/osai-hook",
"events": ["release", "health"],
"repos": ["*"],
"format": "json",
"created": "2026-07-20T09:14:02+00:00",
"delivered": 37,
"fails": 0,
"disabled": null
}
],
"meta": {
"plan": "dev",
"used": 1,
"limit": 3,
"events": ["health", "release", "license", "new_project"],
"formats": ["json", "slack", "discord"],
"delivery": "täglich, nach dem morgendlichen Scan",
"signature": "X-OSAI-Signature: sha256=HMAC_SHA256(body, secret)"
}
}delivered ist die Lebensdaueranzahl erfolgreicher POSTs. fails ist die aktuelle aufeinanderfolgende Serie, sodass sie beim nächsten Erfolg auf 0 zurückfällt. disabled ist null oder der Zeitstempel, zu dem wir gestoppt haben. Geheimnisse werden niemals von GET zurückgegeben.
Vier Möglichkeiten, wie Lieferungen stoppen
- Ihr Endpunkt schlägt ständig fehl. Zehn Fehler hintereinander und der Webhook ist deaktiviert. Beheben Sie den Endpunkt, löschen Sie den Webhook, erstellen Sie einen neuen, pingen Sie ihn.
- Ihr Plan wird auf kostenlos zurückgesetzt — eine Stornierung. Der Webhook bleibt erhalten und wird bei jeder Zustellung stillschweigend übersprungen. Ein erneuter Planwechsel weckt ihn wieder, dieselbe ID, dasselbe Geheimnis.
- Sie rotieren Ihren API-Schlüssel in Ihrem Konto. Der alte Schlüssel verlässt den Schlüssel-Speicher, während der Webhook weiterhin darauf verweist: Er fällt aus Ihrer Liste, kann nicht mehr gepingt oder gelöscht werden, und jede Zustellung überspringt ihn wie einen kostenlosen Schlüssel. Löschen Sie Ihre Webhooks, bevor Sie den Schlüssel rotieren, und erstellen Sie sie dann erneut mit dem neuen.
- Sie löschen ihn. Die Lieferungen stoppen sofort.
Testen ohne Warten
curl -sS -X POST https://olud.ai/api/webhooks.php \
-H "X-Api-Key: $OSAI_KEY" -H "Content-Type: application/json" \
-d '{"ping":"whk_9b41c7e2f0a5d3861c4e"}'Beide Ergebnisse
HTTP/1.1 200
{"ok":true,"data":{"ping":"delivered","http":200}}
HTTP/1.1 502
{"ok":false,"error":{"code":"ping_failed",
"message":"Ihr Endpunkt antwortete mit HTTP 500 — ein 2xx wird erwartet."}}Der Ping wird im Format des Webhooks gesendet, auf die gleiche Weise signiert, mit Ereignis-Ping und Repo null. Er bewegt sich weder als geliefert noch schlägt er fehl, sodass ein fehlgeschlagener Ping Sie niemals in Richtung der Deaktivierungsschwelle drängt. Es funktioniert auch in einem kostenlosen Plan, wenn der Webhook bereits existiert, während geplante Lieferungen nicht funktionieren.
HTTP 0 in einer ping_failed-Nachricht bedeutet, dass wir überhaupt keine Antwort erhalten haben: Der Host konnte nicht aufgelöst werden, TLS wurde nicht abgeschlossen oder die 6 Sekunden sind abgelaufen.
Fehlercodes
Jeder Fehler kommt in derselben Form zurück, mit einem passenden HTTP-Status.
{
"ok": false,
"error": {
"code": "bad_url",
"message": "URL muss https, öffentlich erreichbar, Standardport (kein localhost oder private Bereiche) sein."
}
}| HTTP | code | Wann |
|---|---|---|
| 400 | bad_json | Der Körper ist kein JSON-Objekt. |
| 400 | bad_url | Die URL hat die Überprüfung nicht bestanden: nicht https, ein anderer Port als 443, localhost, .local, .internal oder eine Adresse in einem privaten oder reservierten Bereich. |
| 400 | bad_events | Nach der Filterung enthielten die Ereignisse keine von health, release, license, new_project. |
| 400 | bad_repos | Kein Eintrag war "*" oder ein gültiger Besitzer/Name. |
| 400 | too_many_repos | Mehr als 100 Repositories bei einem Webhook. |
| 400 | bad_format | Format war nicht json, slack oder discord. |
| 401 | missing_key | Kein X-Api-Key-Header und kein ?key= Parameter. |
| 403 | bad_key | Der Schlüssel ist nicht in unserem Schlüssel-Speicher. Ein rotierter oder widerrufener Schlüssel landet hier. |
| 403 | paid_feature | Ihr Plan erlaubt 0 Webhooks. |
| 404 | not_found | Die ID im Ping oder in ?id= ist nicht an Ihren Schlüssel angehängt. |
| 405 | method_not_allowed | Eine Methode, die nicht GET, POST oder DELETE ist. |
| 429 | limit_reached | Sie haben bereits so viele Webhooks, wie Ihr Plan erlaubt. |
| 500 | store_write_failed | Wir konnten die Änderung nicht auf die Festplatte schreiben. Versuchen Sie es erneut. |
| 502 | ping_failed | Ihr Endpunkt antwortete auf den Test-Ping mit etwas anderem als einem 2xx. |
Zwei praktische Punkte. Das Verwalten von Webhooks verbraucht nicht Ihr tägliches API-Anfragekontingent — dieser Endpunkt berührt nie den Zähler und sendet keine X-RateLimit-Header. Und DELETE fehlt in der CORS-Allow-Methods-Liste, sodass ein Cross-Origin-Aufruf von einem Browser bei der Vorabprüfung fehlschlägt; löschen Sie serverseitig oder von der Kontoseite, die dieselbe Herkunft hat.
Automatisierungen
n8n: lesen und empfangen
Zwei Knoten decken beide Richtungen ab. Ein HTTP Request-Knoten liest unsere Daten. Ein Webhook-Knoten empfängt unsere Ereignisse. Nichts aus der Community-Liste zu installieren.
Katalog lesen
Jeder Endpunkt antwortet mit GET unter https://olud.ai/api/v1, mit Ihrem Schlüssel im X-Api-Key-Header. /meta ist der eine Endpunkt, der ohne Schlüssel antwortet und Ihr Kontingent nicht berührt — verwenden Sie ihn als ersten Knoten, während Sie testen, da er die URL und den Netzwerkpfad überprüft, bevor Sie einen Aufruf tätigen.
Ereignisse empfangen
Fügen Sie einen Webhook-Knoten hinzu, Methode POST, und kopieren Sie seine Produktions-URL. Registrieren Sie diese URL in Ihrem Konto (Webhooks-Bereich) oder POSTen Sie sie an https://olud.ai/api/webhooks.php mit Ihrem Schlüssel. Vier Ereignisse zur Auswahl: release, health, license, new_project. Lieferungen erfolgen einmal täglich, in demselben Durchgang, der die E-Mail-Benachrichtigungen sendet — nicht in dem Moment, in dem etwas passiert.
Ein Lieferkörper, im Format json (das Standardformat):
Was in den Daten steht, hängt vom Ereignis ab:
- release — tag, name, url (die Releases-Seite des Repositories)
- health — from, to, stars, page
- license — from, to
- new_project — stars, page
- ping — message (nur Testlieferungen)
Bei einem Gesundheitsereignis sind from und to Labels, keine Zahlen: Thriving (Punktzahl 85 und höher), Healthy (70+), Maintained (50+), Slowing down (30+), At risk (unter 30). Vergleichen Sie Text in Ihrem IF-Knoten, nicht Ganzzahlen.
Jede Lieferung trägt drei Header: X-OSAI-Event, X-OSAI-Delivery (eine eindeutige ID pro Lieferung, verwenden Sie sie, um Duplikate zu entfernen) und X-OSAI-Signature, in der Form sha256=<HMAC-SHA256 des Körpers mit Ihrem Webhook-Geheimnis>. Das HMAC deckt die genauen Bytes ab, die wir gesendet haben, also wenn Sie es verifizieren möchten, aktivieren Sie die raw-body-Option des Webhook-Knotens. Ein Körper, der geparst und erneut serialisiert wurde, stimmt niemals überein.
Fügen Sie dies auf der Leinwand ein. Die beiden Knoten sind absichtlich unverbunden — jeder ist sein eigener Ausgangspunkt:
Dann geben Sie Ihren Schlüssel in das Header-Feld des HTTP-Knotens ein und aktivieren Sie den Workflow — die Produktions-URL eines Webhook-Knotens hört nur zu, während der Workflow aktiv ist.
Wenn nichts ankommt
- Die Registrierung der URL antwortet mit 400 bad_url: der Endpunkt muss https sein, auf Port 443, auf einem öffentlich auflösbaren Host. Ein selbst gehostetes n8n über http, auf localhost, auf einem *.local-Namen oder in einem privaten IP-Bereich wird abgelehnt.
- Die Registrierung antwortet mit 403 paid_feature: Webhooks beginnen im Dev-Plan — 3 Endpunkte im Dev, 10 im Pro, 50 im Org. Ein kostenloser Schlüssel kann keinen erstellen.
- Die Registrierung antwortet mit 429 limit_reached: Sie haben bereits so viele Webhooks, wie Ihr Plan erlaubt. Löschen Sie zuerst einen.
- Warten Sie nicht bis morgen, um es herauszufinden: POST {"ping":"whk_…"} an /api/webhooks.php und das Testereignis verlässt sofort, in derselben Form wie ein echtes. Wenn Ihr Endpunkt nicht mit 2xx antwortet, erhalten Sie 502 ping_failed mit dem Code, den er zurückgegeben hat.
- Zehn aufeinanderfolgende Nicht-2xx-Antworten deaktivieren den Webhook stillschweigend. Ein Erfolg setzt den Zähler zurück. Ein deaktivierter Webhook kommt nur zurück, indem er neu erstellt wird. Die Lieferzeitüberschreitung beträgt 6 Sekunden, sodass ein Knoten, der langsam antwortet, als Fehler zählt.
- Der Webhook wurde erstellt, aber nichts wird geliefert und es gibt keine Fehler: Überprüfen Sie den Plan für den Schlüssel, der ihn besitzt. Wenn er auf Free zurückgefallen ist, werden die Lieferungen übersprungen, während der Endpunkt registriert bleibt.
- Das Geheimnis wird einmal bei der Erstellung angezeigt. Es gibt keine Möglichkeit, es zurückzulesen — löschen und neu erstellen.
Zapier und Make
Die gleichen zwei Richtungen, derselbe Schlüssel, keine App, die in ihren Verzeichnissen gefunden werden kann.
Empfangen: den Hook abfangen
In Zapier: Webhooks von Zapier, Trigger Catch Hook. In Make: das Webhooks-Modul, benutzerdefinierter Webhook. Beide geben Ihnen eine https-URL auf ihrer eigenen Domain, die unseren Test besteht. Fügen Sie sie in Ihr Konto als Webhook-Endpunkt ein, wählen Sie Ihre Ereignisse aus und senden Sie sich dann einen Ping und bestätigen Sie, dass der Zap oder das Szenario ihn erhält, bevor Sie die Schritte dahinter erstellen.
Wenn Sie die X-OSAI-Signature verifizieren möchten, benötigen Sie den Rohkörper und die Header. In Zapier bedeutet das Catch Raw Hook anstelle von Catch Hook. In Make aktivieren Sie die Webhook-Einstellung, die die Anfrage-Header beibehält. Unsere Signatur ist ein HMAC über die genauen Bytes des Körpers, sodass ein Schritt, der das JSON parst, bevor Sie es sehen, den Vergleich unmöglich macht.
Lesen: ein HTTP-Schritt
Zapier's Webhooks GET-Aktion oder Makes HTTP-Modul. Ein Schritt, ein Header:
Ein Erfolg ist {"ok":true,"data":[…],"meta":{…}}. Ein Fehler ist {"ok":false,"error":{"code":"…","message":"…"}} mit einem passenden HTTP-Status. Testen Sie ok, bevor Sie Felder zuordnen: Ein Fehlerkörper hat überhaupt keine Daten, und eine Zuordnung, die data[0] bei einem Fehler liest, produziert stillschweigend leere Werte im Folgenden.
- 401 missing_key — der Header ist nicht angekommen. Überprüfen Sie, ob der Schritt ihn bei jedem Aufruf sendet, nicht nur beim ersten.
- 403 invalid_key — Schlüssel unbekannt oder widerrufen.
- 429 quota_exceeded — tägliches Kontingent erreicht, setzt sich um 00:00 UTC zurück. Erfolgreiche Antworten tragen X-RateLimit-Limit und X-RateLimit-Remaining, sodass Sie es kommen sehen können.
- 503 graph_unavailable — der Graph wird neu aufgebaut. Versuchen Sie es in einer Minute erneut; dies ist der eine Fehler, der einen automatischen Retry wert ist.
- 403 pro_required — /history/{slug} ist nur für Pro und Org.
- 404 not_found — kein solches Projekt oder Produkt. Die Nachricht enthält einen /search-Vorschlag, dem Sie folgen können.
GitHub Action: Abhängigkeitsüberwachung
Die Aktion liest die Abhängigkeitsmanifeste des ausgecheckten Repositories, fragt uns die Lizenz und den Wartungsbericht jeder Abhängigkeit an und postet einen Kommentar zur Pull-Anfrage, in dem aufgeführt ist, was eine Entscheidung benötigt. Es schreibt denselben Kommentar bei jedem Durchlauf um — es findet ihn wieder durch einen versteckten Marker — sodass eine lange Pull-Anfrage nicht mit Duplikaten überfüllt wird.
Der gesamte Workflow, mit jedem Eingabewert auf dem Standardwert. Nur der api-key ist erforderlich:
actions/checkout muss zuerst kommen: die Aktion liest Dateien aus dem Arbeitsverzeichnis, und nur im Root, es sei denn, Sie setzen Pfade.
| Eingabe | Standard | Was es tut |
|---|---|---|
| api-key | erforderlich | Gesendet als X-Api-Key. Eine Abfrage pro distinct dependency. Ein kostenloser Schlüssel funktioniert. |
| github-token | ${{ github.token }} | Postet den Kommentar. Benötigt Pull-Requests: schreiben Sie im Job. |
| health-floor | 45 | Kennzeichnen Sie eine Abhängigkeit, die unter diesem Wert von 100 liegt. 0 schaltet die Gesundheitsprüfung aus und behält nur Lizenzen. Lesen Sie die bekannte Grenze unten. |
| lizenzen | AGPL-3.0,BSL-1.1,SSPL-1.0,Elastic-2.0,BUSL-1.1,NOASSERTION | Durch Kommas getrennt, ohne Berücksichtigung der Groß- und Kleinschreibung mit der Lizenz, die wir halten. Das Setzen ersetzt die Liste, es wird nicht hinzugefügt. |
| fail-on-finding | false | Fehler bei der Überprüfung anstelle von nur Kommentieren. |
| pfade | leer | Durch Kommas getrennte Manifeste zum Lesen. Leer bedeutet: Suchen Sie nach den vier bekannten Namen im Root. |
NOASSERTION ist absichtlich in der Standardliste: es ist das, was wir halten, wenn das Repository keine Lizenzdatei hat, die eine Maschine erkennen kann, was eine Entscheidung ist, die zu treffen ist, und kein Detail. Die Aktion gibt einen Output aus, findings — die Anzahl der gekennzeichneten Abhängigkeiten, die auch geschrieben werden, wenn sie 0 ist.
Was es liest
- package.json — die Schlüssel von dependencies und devDependencies. peerDependencies und optionalDependencies werden nicht gelesen.
- requirements.txt — ein Name pro Zeile, Kommentare entfernt, Zeilen, die mit - beginnen, werden verworfen. Also wird -r other-requirements.txt nicht befolgt und -e . wird ignoriert.
- pyproject.toml — nur Schlüssel, deren Wert mit einem Anführungszeichen oder einer geschweiften Klammer beginnt, was dem Poetry-Stil entspricht: fastapi = "^0.110". Ein PEP 621 Block, dependencies = ["fastapi>=0.110"], ergibt überhaupt nichts.
- go.mod — eingerückte Zeilen der Form name vX.
Pfade können irgendwo im Baum zeigen, zum Beispiel apps/api/requirements.txt, aber der Basisname der Datei muss einer dieser vier sein. Eine Datei namens requirements-dev.txt hat keinen Parser: sie wird ohne Nachricht übersprungen.
Wie es fehlschlägt
- Kein Manifest im Root oder kein Checkout-Schritt: "Kein Abhängigkeitsmanifest gefunden — nichts zu überprüfen." findings ist 0 und der Job ist grün. Ein grüner Lauf bedeutet nicht einen sauberen Baum — lesen Sie diese Zeile.
- Das Ereignis hat keinen Pull-Request, zum Beispiel bei einem Push: "Kein Pull-Request im Kontext — Kommentar übersprungen." Die Findings sind weiterhin im Protokoll.
- pull-requests: schreiben fehlt: "Kommentar konnte nicht gepostet werden (HTTP 403)." Der Job bleibt grün und der Kommentar erscheint nie. Schauen Sie sich das Protokoll an, nicht den Pull-Request.
- Tägliches API-Kontingent während des Laufs erreicht: ::warning::Tägliches API-Kontingent erreicht — teilweiser Lauf. Es hört auf, Dinge nachzuschlagen und kommentiert, was es geschafft hat zu lösen. Ein Aufruf pro distinct dependency, also verbrauchen 300 Abhängigkeiten 300 der 500 täglichen Aufrufe eines kostenlosen Schlüssels.
- Ein Manifest, das nicht geparst werden kann: "⚠ <file> nicht lesbar (…) — übersprungen". Die anderen Manifeste laufen weiterhin.
- Der zusammengesetzte Schritt führt node aus dem PATH aus und verwendet native fetch. GitHub-gehostete Runner haben bereits Node 20. Ein selbstgehosteter Runner benötigt actions/setup-node mit Node 20 oder höher.
- lizenzen: '' mit health-floor: '0' erzeugt für immer null Findings. Diese Kombination schaltet beide Prüfungen aus.
Was der Action fehlt
Ein Paketname ist kein Repository-Name. Jeder Name wird durch /api/v1/search?q=<name>&limit=5 geleitet und die Aktion behält ein Ergebnis nur, wenn der Projektname gleich dem Paketnamen ist, ohne Berücksichtigung der Groß- und Kleinschreibung. Alles andere wird stillschweigend verworfen — keine Kommentarzeile, keine Warnung. Das Raten des nächsten Ergebnisses würde Alarm über das falsche Projekt auslösen, was schlimmer ist, als still zu bleiben, aber es bedeutet, dass die Überprüfung weniger als Ihren Abhängigkeitsbaum abdeckt.
- Scoped npm-Pakete verlieren ihren Scope vor der Abfrage: @types/node wird als node gesucht, was mit einem nicht verwandten Repository dieses Namens übereinstimmen kann. Dies ist der eine Fall, in dem das falsche Projekt im Kommentar enden kann.
- Go-Module behalten ihren Pfad: github.com/gin-gonic/gin wird zu gin-gonic/gin, was niemals einem Repository-Namen (gin) entspricht. go.mod-Abhängigkeiten lösen sich nicht auf.
- Ein Paket, dessen Repository anders benannt ist — der häufige Fall in Python — löst niemals auf.
- Nur die fünf besten Ergebnisse werden untersucht und nur die erste exakte Übereinstimmung wird verwendet. Wenn zwei Repositories denselben Namen haben, gewinnt das mit mehr Sternen.
Die Zeile, die im Protokoll gelesen werden muss, lautet: Resolved N von M Abhängigkeiten · K markiert. Wenn N weit unter M liegt, hat die Überprüfung nur einen Teil Ihres Baums betrachtet. Nichts im Kommentar der Pull-Anfrage sagt das aus.
OpenAPI-Spezifikation
Eine Datei beschreibt die Lese-API: https://olud.ai/openapi.json. OpenAPI 3.0.3, ein Server (https://olud.ai/api/v1), neun GET-Operationen, ein Sicherheitskonzept — ein API-Schlüssel im X-Api-Key-Header. Sie schreiben keine Integration; Sie fügen eine Adresse ein.
- /meta — Erstellungsdatum und Projektanzahl. Ohne Sicherheit deklariert: es ist die Gesundheitsprüfung.
- /search — q erforderlich, Limit 1 bis 50, Standard 15.
- /projects — lang, lizenz, vertikal, health_min 0 bis 100, sortieren nach stars|health|momentum|recent (Standard stars), Limit 1 bis 100 (Standard 25), Offset 0 bis 100000 (Standard 0).
- /project/{id} — der vollständige zusammengeführte Datensatz, einschließlich Gesundheit mit ihren Komponenten.
- /emerging — Limit 1 bis 100, Standard 25.
- /alternatives/{product} — Open-Source-Alternativen zu einem kommerziellen Produkt.
- /models — Anbieter, Stufe, Limit 1 bis 200 (Standard 50), Offset.
- /hf — am häufigsten heruntergeladen und im Trend auf Hugging Face.
- /history/{slug} — 90 Tage Sterne, Gesundheit und Momentum. Pro und Org.
Importieren Sie es
- Custom GPT — Konfigurieren, dann Aktionen, dann Import von URL. Authentifizierung: API-Schlüssel, benutzerdefinierter Header, Name X-Api-Key.
- Dify, Flowise, Open WebUI — fügen Sie ein Tool aus einem OpenAPI-Schema hinzu, fügen Sie die URL ein, wählen Sie die Operationen aus, die Sie freigeben möchten, fügen Sie denselben Header hinzu.
- Postman, Insomnia — Importieren, dann Link. Sie erhalten die neun Anfragen, dokumentiert. Setzen Sie X-Api-Key einmal auf Sammlungsebene, damit jede Anfrage ihn erbt.
- Code-Generatoren — jeder OpenAPI-Generator erzeugt einen typisierten Client, TypeScript, Python oder Go, nur aus dieser Datei.
Egal welches Tool, es gibt nur zwei Dinge einzustellen: die URL der Datei und den Schlüssel als Header mit dem Namen X-Api-Key. Wenn ein Import neun Operationen anzeigt, aber jeder Aufruf mit 401 antwortet, wird der Header nicht gesendet — das ist das erste, was zu überprüfen ist.
Kontingente gelten pro Schlüssel und pro Tag, zurückgesetzt um 00:00 UTC: 500 Anfragen im Free-Tarif, 5.000 im Dev-Tarif, 50.000 im Pro-Tarif, 500.000 im Org-Tarif. Sie werden separat vom MCP-Server gezählt, sodass ein Assistent, der Fragen in Ihrem Editor stellt, niemals in dieses Budget eingreift.
Vier RSS-Feeds
Kein Schlüssel, keine Anmeldung, kein Konto. feed.php akzeptiert genau vier Typen: Nachrichten, Blog, Releases, Emerging.
| URL | Was es trägt | Woher es kommt |
|---|---|---|
| /feed.php | Bis zu 30 neue Projekte (★Sterne · Eigentümer/Name), die neuen Modelle des Tages (Neues Modell: Name (Anbieter), mit dem Kontextfenster in der Beschreibung), neue Hugging Face Spaces (Neuer Space: Name des Autors, mit der Anzahl der Likes) und das Papier des Tages. | today-data.json, stündlich neu aufgebaut |
| /feed.php?type=releases | Bis zu 60 Versionen, die von den Projekten, die wir verfolgen, ausgeliefert werden: Titel Projekt + Tag, Link zur Veröffentlichung, guid Eigentümer/Name@Tag. | releases-data.json, stündlich neu aufgebaut |
| /feed.php?type=emerging | Bis zu 40 aufstrebende Projekte — gesund, beschleunigend, noch wenig bekannt. Beschreibung: ★Sterne · Gesundheit N/100 · +N Sterne diese Woche. | das Diagramm, jeden Morgen neu aufgebaut |
| /feed.php?type=blog | Artikel unter /blog/<slug>/, /blog/alternatives/ und /reports/. Titel und Beschreibung sind der eigene Titel und die Meta-Beschreibung der Seite; das Datum ist die Änderungszeit der Datei. | von der Festplatte lesen, sodass ein neuer Artikel von selbst erscheint |
Alle vier antworten mit RSS 2.0 als application/rss+xml, in Englisch, neuester Artikel zuerst, mit Cache-Control: public, max-age=1800. Das sind 30 Minuten: Ein Leser, der häufiger abfragt, erhält die zwischengespeicherte Kopie, die dieselbe Antwort schneller liefert.
Guids sind stabil und nicht immer der Link, was Sie beim Duplizieren in einer Automatisierung wollen: Releases verwenden owner/name@tag, aufstrebende Projekte verwenden emerging:<id>, das Papier des Tages verwendet seine URL plus das Datum, alles andere verwendet seinen Link.
Richten Sie Slack, Teams oder Feedly auf sie aus, um zu lesen, oder verwenden Sie den RSS-Trigger in n8n, Zapier und Make, wenn ein Zeitplan besser zu Ihnen passt als ein Webhook — das ist auch der Weg, um Releases ohne einen kostenpflichtigen Plan zu erhalten. Wenn eine Quelldatei nicht neu erstellt wurde, antwortet der Feed weiterhin mit 200 und einem leeren Kanal anstelle eines Fehlers, sodass eine Automatisierung, die plötzlich nichts erhält, nicht unbedingt defekt ist.