Contacts

Get a contact lookup

Changed on

Free. Poll the job_id from a contact lookup that returned HTTP 202, every few seconds, until status is completed. Requires contacts:spend. status is pending until every person is stored, then completed with the emails, phones, best_email, and best_phone. cost.credits, credits_charged, and each person's credits are the credits that job charged, read from the ledger. While the job is pending they are all 0. charged_this_request is 0 while pending; once completed it is the same number as credits_charged, because the lookup that started the job is charged when the job completes. The poll itself never charges: X-Credits-Charged is 0 and polling again charges nothing more. An idempotent replay of the original lookup has charged_this_request 0 and cost.credits 0.

Polling example:

KEY="<your API key>"
curl -s -X POST https://api.recruitmcp.com/v1/people/contacts:fetch \
  -H "Authorization: Bearer $KEY" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" -d '{"profile_ids":["lead_8f2a1c_1"]}'
# 202: {"status":"pending","job_id":"cjob_01J0CJOB0EXAMPLE","poll_url":"/v1/contacts/jobs/cjob_01J0CJOB0EXAMPLE",...}
# Poll until status is completed (pending until then). The wait doubles from 2 s up to 30 s; stop on an error, give up after about 2 minutes.
delay=2
for i in 1 2 3 4 5 6 7 8; do
  body=$(curl -sS https://api.recruitmcp.com/v1/contacts/jobs/cjob_01J0CJOB0EXAMPLE -H "Authorization: Bearer $KEY")
  echo "$body" | grep -q '"status":"completed"' && break
  echo "$body" | grep -q '"error":{' && break
  sleep $delay
  delay=$((delay*2>30?30:delay*2))
done
echo "$body"
# data[].contacts.best_email and best_phone; credits_charged and charged_this_request equal cost.credits

Scope: contacts:spend.

get/v1/contacts/jobs/{job_id}

Request

  • Base URL: https://api.recruitmcp.com
  • URL: https://api.recruitmcp.com/v1/contacts/jobs/{job_id}
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://recruitmcp.com/oauth/authorize, token URL https://recruitmcp.com/oauth/token, scopes: contacts:spend)

Path parameters

job_idstring required
Example:cjob_01J0CJOB0EXAMPLE

Headers

RecruitMCP-Version'2026-10-13'

API version. Defaults to the version the key was created with. Supported: 2026-10-13.

RecruitMCP-Customerstring

Act inside this customer (cus_…). Ignored for keys bound to a customer, which always act inside theirs.

Response

The lookup, pending or completed.

status'pending' | 'completed'

pending while the lookup is running. completed when the job poll has the stored contacts.

request_idstring nullable

Id of the running lookup.

job_idstring

Set on HTTP 202. Poll GET /v1/contacts/jobs/{job_id}.

poll_urlstring

Path of GET /v1/contacts/jobs/{job_id}. Requires contacts:spend.

canonical_idstring nullable

Search id when one person was requested.

charged_this_requestnumber

Credits charged for the lookup this body describes. Matches cost.credits. On a 202 and on a pending poll it is 0. On a completed poll it is what the lookup that started the job was charged at completion, the same as credits_charged; the poll itself charges nothing. 0 on an idempotent replay, where cost.credits is also 0.

credits_chargednumber

Set on a contact job (HTTP 202 and GET /v1/contacts/jobs/{job_id}). Credits the ledger charged for this job: 0 while pending, then the same number as cost.credits.

Example response

{
  "data": [
    {
      "profile_id": "lead_8f2a1c_1",
      "contacts": {
        "status": "ready",
        "emails": [
          {
            "value": "ada.peeters@example.com",
            "type": "personal",
            "line": "personal",
            "confidence": 0.9
          }
        ],
        "phones": [
          {
            "value": "+447700900001",
            "type": "personal",
            "line": "mobile",
            "confidence": 0.8
          }
        ],
        "best_email": {
          "value": "ada.peeters@example.com",
          "type": "personal",
          "line": "personal",
          "confidence": 0.9,
          "reason": "only_candidate"
        },
        "best_phone": {
          "value": "+447700900001",
          "type": "personal",
          "line": "mobile",
          "confidence": 0.8,
          "reason": "only_candidate"
        },
        "expires_at": "2026-11-12T09:00:00Z"
      },
      "credits": 25,
      "cost": {
        "credits": 25,
        "cached_items": 0,
        "live_items": 1,
        "upstream_calls": 1
      }
    }
  ],
  "cost": {
    "credits": 25,
    "cached_items": 0,
    "live_items": 1,
    "upstream_calls": 1
  },
  "charged_this_request": 25
}

Changes

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status

    • warning

      added the new approval_forced enum value to the / response property for the response status