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.

Terminal
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

  1. Create a project at no charge with POST /api/v1/projects.
  2. Ask for each missing_fields value and add it with PATCH /api/v1/projects/{id} until state=ready.
  3. Confirm the paid action, then call POST /api/v1/projects/{id}/source.
  4. Check status no more than every 15–30 minutes until state=delivered.
  5. Retrieve candidates by tier and page.
  6. 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_rawstring

Vollständige Stellenbeschreibung als Text.

role_titlestring

Zieltitel der Rolle, zum Beispiel Senior Sales Executive Luftfracht.

company_namestring

Final einstellendes Unternehmen; dessen aktuelle Mitarbeitende werden automatisch ausgeschlossen.

work_location_citystring

Stadt des tatsächlichen Arbeitsorts.

work_location_postal_codestring

PLZ des tatsächlichen Arbeitsorts; für Deutschland fünfstellig. Bestimmt den Standort der Suche.

country_codestring

Zweibuchstaben-Ländercode in Großbuchstaben, aktuell DE.

home_office_percentinteger 0–100

Home-Office-Anteil von 0 bis 100; steuert die Radius-Strategie.

remote_policy_rawstring

Originale Remote- bzw. Hybrid-Formulierung; Nuancen zählen.

max_salary_eur_gross_annualinteger

Jahresbrutto-Obergrenze in EUR; kalibriert die Bewertung und wird nie veröffentlicht.

Optional fields

free_textstring

Weitere Must-haves, Sprachen, Ausschlüsse und Teamkontext.

suppress_companiesarray

Unternehmen, 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.

Incomplete POST response · HTTP 201
{
  "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.

POST/api/v1/projects201 · 401 · 422 · 429 · 500

Sourcing-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.

PATCH/api/v1/projects/{id}200 · 401 · 404 · 409 · 422 · 429 · 500

Projekt-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.

POST/api/v1/projects/{id}/source202 · 401 · 402 · 404 · 409 · 422 · 429 · 500

Sourcing 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.

GET/api/v1/projects/{id}200 · 401 · 404 · 429 · 500

Projektstatus 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.

GET/api/v1/projects200 · 401 · 429 · 500

Projekte auflisten

Listet alle Projekte Ihres Accounts, absteigend nach Erstellungszeit, mit Zustand und Eckdaten auf.

GET/api/v1/projects/{id}/candidates200 · 401 · 404 · 409 · 429 · 500

Kandidaten 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.

POST/api/v1/projects/{id}/feedback201 · 401 · 404 · 422 · 429 · 500

Feedback 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.

GET/api/v1/account200 · 401 · 429 · 500

Account 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.

GET/api/v1/openapi.json200

OpenAPI-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_identifier

Stabiler LinkedIn-Slug und Identitätsschlüssel; niemals anhand des Namens abgleichen.

rank_position

Rang in der Gesamtliste.

tier
full_name
current_title
current_company
location_label
linkedin_url
profile_json

Allowlist-basierte Profilfakten aus dem LinkedIn-Profil. Null, wenn keine verwertbaren Profilfakten vorliegen. Enthält niemals Scores, Evaluationen, Provider-Metadaten oder Outreach-Signale.

reasoning

Kalibrierte 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 401

Der API-Key fehlt, ist fehlerhaft oder ungültig, wurde widerrufen oder der Account ist inaktiv.

insufficient_creditsHTTP 402

Es ist kein passendes offenes Job-Paket bzw. Top-up verfügbar. Das Fehlerobjekt enthält purchase_urls.

validation_errorHTTP 422

Ein übergebener Wert ist ungültig. Fehlende Intake-Pflichtfelder bei POST/PATCH sind dagegen Daten und kein 422-Fehler.

not_foundHTTP 404

Das Projekt existiert nicht oder gehört nicht zu Ihrem Account.

not_readyHTTP 409

Die Aktion ist im aktuellen Projektzustand nicht möglich. Das Fehlerobjekt kann state enthalten.

rate_limitedHTTP 429

Das Limit pro API-Key ist erreicht. REST und MCP antworten mit HTTP 429, Retry-After und retry_after in Sekunden.

internalHTTP 500

Ein unerwarteter Serverfehler ist aufgetreten. Bewahren Sie die request_id für den Support auf.

429 · REST and MCP
{
  "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.