Nyne.ai API Get API key
Core Concepts

Async requests, polling & webhooks

Most Nyne.ai data endpoints are asynchronous. A POST validates your request, checks account access and available credits when applicable, and enqueues the work, then returns 202 with a request_id. The result is not in that response - you poll the same path until it returns a terminal response, or hand over a callback_url and let a webhook deliver it. This guide covers the request lifecycle, correct polling, terminal errors, and callback webhooks.

  1. queued
    202

    Accepted and enqueued. Nothing has run yet.

  2. processing
    200 or 202

    Check completed and keep polling.

  3. completed
    200

    A match. completed: true, result attached.

    failed / error
    200 or 4xx/5xx

    Endpoint-specific terminal failure. Stop polling that request.

Submit, 202, poll

A POST to a data endpoint validates your input, checks account access and available credits when applicable, and enqueues background work. It returns 202 Accepted with a request_id that identifies this one job. The result is not in that response; the acknowledgement carries a non-terminal status such as queued or processing.

curl -X POST https://api.nyne.ai/person/enrichment \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "email": "jane.doe@acme.com" }'

The 202 body hands you the request_id to poll with next:

{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "queued",
    "message": "Enrichment request queued. Use GET /person/enrichment?request_id=... to check status."
  },
  "timestamp": "2026-05-28T18:04:11"
}

The lifecycle statuses

The submit/queue reply contains a non-terminal status such as queued or processing. From then on, the status endpoint commonly returns: pending, processing, completed, or failed. A representative progression is queued -> processing -> completed.

  • Most endpoints use completed for terminal success (never "done"). Some endpoint pages document additional successful terminal values. For example, People Search can return exhausted or stale with completed: true.
  • A successful poll may use 200 or 202 while work is still in flight. When a successful payload includes completed, keep polling while it is false and stop when it is true; otherwise use the endpoint's status table. HTTP 200 alone does not prove completion. A terminal error envelope or non-retriable non-2xx processing/billing response also stops that request; transient transport/status-infrastructure responses may be retried using the endpoint's documented backoff policy.
Use only documented status values
Treat the status values listed here and on each endpoint page as the complete public contract. Do not infer additional intermediate states. See Interpreting responses for the full status model.

Poll for the result

Poll by sending a GET to the same path you POSTed to, with ?request_id=... and any additional page values required by that endpoint. You may get 200 or 202 while the job is in progress. When completed is present on a successful response, continue while it is false and stop when it is true. Otherwise follow the endpoint's status table. Any terminal error envelope or non-retriable non-2xx job response also stops that request; retry transient transport/status-infrastructure responses only as documented by the endpoint.

curl "https://api.nyne.ai/person/enrichment?request_id=a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET"
Poll once a second, and back off
Enrichment usually finishes in well under a second, so the first poll often already returns the result. Poll roughly once per second with a sensible max-wait; do not hammer the endpoint. Polls count toward your throttles, so see the Rate limits guide before tightening the loop.

A successful terminal payload carries the merged, sanitized result inside the same envelope, with status: "completed" and completed: true:

{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "completed",
    "completed": true,
    "result": {
      "displayname": "Jane Doe",
      "headline": "VP of Product at Acme",
      "location": "San Francisco, CA",
      "best_business_email": "jane.doe@acme.com"
    },
    "error": null,
    "created_on": "2026-05-28T18:04:11",
    "completed_on": "2026-05-28T18:04:39"
  },
  "timestamp": "2026-05-28T18:04:45"
}

A status lookup itself can fail. The request must belong to the authenticating key, the request_id must be known, and the lookup store must be reachable. Treat authentication, authorization, unknown-request, insufficient-credit, and terminal processing errors as settled. Retry a 429 poll only when the poll itself was throttled; a 429 stored as the job's terminal status ends that request. Back off and retry transient service-unavailable responses:

error.codeHTTPMeaning
invalid_credentials401Authentication failed. Fix credentials before retrying.
insufficient_credits402The job cannot continue until the account has enough credits.
access_denied / ip_not_allowed403The authenticated account or request IP is not allowed.
request_not_found404No request matches that request_id, including IDs owned by another API key.
rate_limit_exceeded429If the poll itself was throttled, honor Retry-After and retry it. If this is the job's stored terminal status, stop polling that request_id and submit a new request after the limit resets.
search_error / internal_error500Terminal processing failure unless the endpoint says otherwise.
service_unavailable503A transient lookup issue. Back off and retry.

Webhooks with callback_url

Instead of polling, supply a callback_url on the submit. When the job completes, Nyne.ai POSTs the same result envelope to your URL:

curl -X POST https://api.nyne.ai/person/enrichment \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
        "email": "jane.doe@acme.com",
        "callback_url": "https://hooks.example.com/nyne"
      }'

The callback URL is validated before the request is accepted. It must be http(s)://, at most 1024 characters, and carry no userinfo (no user:pass@ in the URL). It is also checked against an allowed-hosts policy that rejects localhost, private, and reserved addresses, along with .local, .internal, .lan, .home, .corp, .test, .invalid, and .example hosts. An invalid target is rejected at submit time with 400 invalid_callback_url.

Handle deliveries idempotently
For endpoints using the common callback envelope, the delivered payload matches what a poll would have returned: success, data (with the terminal status and result), and timestamp. Verify and process it idempotently, keyed on the request_id, so a retried delivery is safe.

Person Search has endpoint-specific pagination behavior. Its callback can report queued session work, but it is not a per-page pagination mechanism. After a successful callback it is not re-emitted for every later page, and an immediately cached page POST does not enqueue one. The exact GET /person/search request with that page's request_id, offset, and limit remains the authoritative retrieval path. See Person Search.

Which calls are synchronous

Not everything is async. A few calls return 200 directly, with no request_id and nothing to poll:

  • POST /person/enrichment/feedback is a single insert that returns 200 immediately.
  • The status-lookup GETs themselves are synchronous, and they are not credit-gated - polling never costs credits.

Idempotency and durability

The request_id is the durable handle to one job. Re-polling it with the documented status GET is safe and does not re-charge credits. A poll loop, a retried GET poll, or a redelivered webhook does not create another charge. People Search is the pagination exception: multiple page POSTs reuse one request_id, and each successfully fulfilled page POST is billable; use GET, not POST, for status checks and stored-page reads.

Status GETs are free
Because the handle is stable and GET polling is free, you can safely resume a job from its request_id after a restart, retry a dropped GET poll, or accept a duplicate callback. Do not replace a status GET with another page POST on People Search.

What's next

  • Rate limits - how throttles work so your poll loop stays under them.
  • Interpreting responses - the envelope, the status model, and how normalized statuses are derived.
  • Credits - when a request is charged and what counts as a meaningful result.
  • Your first request - the end-to-end walkthrough this guide builds on.