API v1.3.1 · Updated 2026-07-12
API reference
Merite turns a complete role intake into a ranked, reasoned candidate shortlist. The same workflow is available through the MCP endpoint.
Authentication and rate limits
Except for the public OpenAPI document, every REST request requires your API key as a Bearer token in the Authorization header. Store the key on the server only.
curl https://merite.ai/api/v1/account \
-H "Authorization: Bearer <api-key>"The default limit is 60 requests per minute per API key. Admin keys are exempt. REST and MCP return 429 rate_limited, a Retry-After header, and error.retry_after in seconds when you exceed the limit.
Every REST response is JSON and includes a request_id. Errors always use { error: { code, message, … }, request_id }.
Workflow in six steps
- Create a project at no charge with
POST /api/v1/projects. - Ask for each
missing_fieldsvalue and add it withPATCH /api/v1/projects/{id}untilstate=ready. - Confirm the paid action, then call
POST /api/v1/projects/{id}/source. - Check status no more than every 15–30 minutes until
state=delivered. - Retrieve candidates by tier and page.
- Show the list to a human and return candidate, role, and process feedback.
The state pending_release means: accepted — processing starts shortly. Delivery is usually completed within the same business day.
Intake and missing_fields
Nine business fields must be complete before sourcing starts. They may be omitted from POST and PATCH; the API returns each gap in missing_fields with an explanation. This is a successful clarification loop, not a 422 error. Only an invalid value that was supplied produces validation_error. Never invent intake values.
Required fields
job_description_rawstringVollständige Stellenbeschreibung als Text.
role_titlestringZieltitel der Rolle, zum Beispiel Senior Sales Executive Luftfracht.
company_namestringFinal einstellendes Unternehmen; dessen aktuelle Mitarbeitende werden automatisch ausgeschlossen.
work_location_citystringStadt des tatsächlichen Arbeitsorts.
work_location_postal_codestringPLZ des tatsächlichen Arbeitsorts; für Deutschland fünfstellig. Bestimmt den Standort der Suche.
country_codestringZweibuchstaben-Ländercode in Großbuchstaben, aktuell DE.
home_office_percentinteger 0–100Home-Office-Anteil von 0 bis 100; steuert die Radius-Strategie.
remote_policy_rawstringOriginale Remote- bzw. Hybrid-Formulierung; Nuancen zählen.
max_salary_eur_gross_annualintegerJahresbrutto-Obergrenze in EUR; kalibriert die Bewertung und wird nie veröffentlicht.
Optional fields
free_textstringWeitere Must-haves, Sprachen, Ausschlüsse und Teamkontext.
suppress_companiesarrayUnternehmen, deren aktuelle Mitarbeitende nie in der Kandidatenliste erscheinen dürfen.
language"de" | "en"Ausgabesprache der Begründungen.
The field descriptions below come directly from the German v1 OpenAPI contract and intentionally remain in German.
{
"project_id": "d7c1a9f4-…",
"state": "draft",
"missing_fields": [
{
"field": "work_location_postal_code",
"explanation": "PLZ des tatsächlichen Arbeitsorts; für Deutschland fünfstellig. Bestimmt den Standort der Suche."
}
],
"next_step": "Fehlende Felder per PATCH /v1/projects/{id} ergänzen.",
"request_id": "8f0a1c2e-…"
}UTF-8 on Windows
Write JSON bodies containing German characters to a UTF-8 file without a BOM and send them with --data-binary @body.json. This preserves ä, ö, ü, and ß.
All endpoints
These operations are rendered directly from the published OpenAPI object. Status codes on the right list every documented response. The v1 endpoint summaries and descriptions intentionally remain in German.
/api/v1/projects201 · 401 · 422 · 429 · 500Sourcing-Projekt anlegen
Legt ein neues Projekt kostenfrei an. Sie können alle bereits bekannten Intake-Felder senden. Fehlende Pflichtfelder stehen mit Erklärung in missing_fields; auch ein unvollständiger Intake antwortet mit 201 und nicht mit 422. Nur ungültige übergebene Werte führen zu validation_error. Bei identischer Firma, Rolle und PLZ kann die Antwort einen unverbindlichen Duplikathinweis enthalten.
/api/v1/projects/{id}200 · 401 · 404 · 409 · 422 · 429 · 500Projekt-Intake ergänzen
Ergänzt oder korrigiert bekannte Intake-Felder, solange das Projekt draft oder ready ist. Die Antwort enthält den neuen Zustand und alle weiterhin fehlenden Pflichtfelder. Fehlende Felder sind Daten und niemals ein 422-Fehler; ungültige übergebene Werte führen zu validation_error.
/api/v1/projects/{id}/source202 · 401 · 402 · 404 · 409 · 422 · 429 · 500Sourcing starten (kostenpflichtig)
Startet das Sourcing und verbraucht dabei genau ein passendes, noch offenes Paket: bei ready ein Job-Paket, bei delivered ein Top-up. Bestätigen Sie diesen kostenpflichtigen Schritt vorher. Ohne passendes Paket antwortet die API mit 402 und purchase_urls. Der zurückgegebene Zustand pending_release bedeutet: Auftrag angenommen — Verarbeitung startet in Kürze. Die Lieferung erfolgt in der Regel am selben Werktag. Ein optionales volume muss exakt dem Paketvolumen entsprechen.
/api/v1/projects/{id}200 · 401 · 404 · 429 · 500Projektstatus abrufen
Liefert Zustand, Fortschrittsnotiz, Budget und gesourcte Anzahl. Bei draft/ready enthält die Antwort missing_fields; nach der Lieferung zusätzlich tier_counts und report_url. Fragen Sie diesen Endpunkt während eines Laufs höchstens alle 15–30 Minuten ab.
/api/v1/projects200 · 401 · 429 · 500Projekte auflisten
Listet alle Projekte Ihres Accounts, absteigend nach Erstellungszeit, mit Zustand und Eckdaten auf.
/api/v1/projects/{id}/candidates200 · 401 · 404 · 409 · 429 · 500Kandidaten abrufen
Liefert die nach rank_position sortierte Kandidatenliste eines gelieferten Projekts. Sie können nach tier filtern und mit offset/limit paginieren. Kundenseitig werden niemals interne oder numerische Scores ausgegeben: Identität, Rang, Tier, strukturierte Profilfakten und – falls aktiviert – die kalibrierte Begründung sind die einzigen Kandidatenfelder.
/api/v1/projects/{id}/feedback201 · 401 · 404 · 422 · 429 · 500Feedback speichern
Speichert Freitext-Feedback auf Kandidaten-, Job- oder Prozessebene. Referenzieren Sie Kandidaten ausschließlich über public_identifier oder linkedin_url, niemals über den Namen. Bei Kandidatenfeedback zeigt candidate_matched, ob die Identität exakt aufgelöst wurde; das Feedback wird auch ohne Treffer gespeichert.
/api/v1/account200 · 401 · 429 · 500Account und Guthaben abrufen
Liefert Accountdaten, alle noch offenen Job-Pakete und Top-ups sowie die konfigurierten Kauf-Links. Das Guthaben wird aus ungenutzten Kauf- und Grant-Einträgen abgeleitet; purchase_urls können bei fehlender Konfiguration null sein.
/api/v1/openapi.json200OpenAPI-Dokument abrufen
Liefert diese handgepflegte OpenAPI-3.1-Beschreibung als JSON. Dieser Endpunkt ist öffentlich und benötigt keinen API-Key.
Candidate contract
GET /api/v1/projects/{id}/candidates becomes available at state=delivered. Filter tier by contact, borderline, or evaluated. offset starts at 0; limit defaults to 100 and cannot exceed 500.
public_identifierStabiler LinkedIn-Slug und Identitätsschlüssel; niemals anhand des Namens abgleichen.
rank_positionRang in der Gesamtliste.
tierfull_namecurrent_titlecurrent_companylocation_labellinkedin_urlprofile_jsonAllowlist-basierte Profilfakten aus dem LinkedIn-Profil. Null, wenn keine verwertbaren Profilfakten vorliegen. Enthält niemals Scores, Evaluationen, Provider-Metadaten oder Outreach-Signale.
reasoningKalibrierte Begründung; fehlt vollständig, wenn EXPOSE_REASONING=false gesetzt ist.
public_identifier is the stable identity key. Never match candidates by name. Internal scores and the evaluation contract are never returned on customer-facing paths. reasoning is omitted entirely when reasoning output is disabled.
Error contract
Additional data lives inside error: purchase_urls for 402, missing_fields for an incomplete start, state for state conflicts, and retry_after for 429.
unauthorizedHTTP 401Der API-Key fehlt, ist fehlerhaft oder ungültig, wurde widerrufen oder der Account ist inaktiv.
insufficient_creditsHTTP 402Es ist kein passendes offenes Job-Paket bzw. Top-up verfügbar. Das Fehlerobjekt enthält purchase_urls.
validation_errorHTTP 422Ein übergebener Wert ist ungültig. Fehlende Intake-Pflichtfelder bei POST/PATCH sind dagegen Daten und kein 422-Fehler.
not_foundHTTP 404Das Projekt existiert nicht oder gehört nicht zu Ihrem Account.
not_readyHTTP 409Die Aktion ist im aktuellen Projektzustand nicht möglich. Das Fehlerobjekt kann state enthalten.
rate_limitedHTTP 429Das Limit pro API-Key ist erreicht. REST und MCP antworten mit HTTP 429, Retry-After und retry_after in Sekunden.
internalHTTP 500Ein unerwarteter Serverfehler ist aufgetreten. Bewahren Sie die request_id für den Support auf.
{
"error": {
"code": "rate_limited",
"message": "Rate-Limit erreicht (60 Anfragen/Minute). Bitte in 37s erneut versuchen.",
"retry_after": 37
},
"request_id": "8f0a1c2e-…"
}The HTTP response also includes Retry-After: 37.