# Interpreting API responses

> Every reply from the Nyne.ai API arrives in the same envelope, so reading one correctly means reading them all. Branch on `success` first, tell a finished result from a still-running one, read confidence scores where they exist, and build against the documented public fields.

HTML version: https://api.nyne.ai/documentation/responses

The shape is always the same: `success` (true or false), then `data` or `error` (one, never both), then `timestamp` (server UTC, ISO-8601). Branch on `success` first; on failure switch on `error.code`, not the message.

## The uniform envelope

Success or failure, from any endpoint, the response is wrapped in the same keys. On success you get `success: true` and the payload under `data`:

```json
{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "completed",
    "completed": true,
    "result": {
      "displayname": "Jane Doe",
      "headline": "VP of Product at Acme",
      "best_business_email": "jane.doe@acme.com"
    }
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

When something goes wrong, `success` is `false`, there is no `data`, and the detail sits under `error`:

```json
{
  "success": false,
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits to complete this request."
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

Always branch on `success` first, then read `error.code` for the failure branch. The `error.code` is a stable, machine-readable identifier; the human `message` is for logs and can change wording at any time, so never parse it. The `timestamp` is the server's UTC time in ISO-8601 - useful for correlating logs, not for logic.

## Async status: done or not done

Most data endpoints answer asynchronously. A `202` means the request was accepted but is **not finished**. While it runs, `data.status` reads `pending`, `queued`, or `processing`, and `data.completed` is `false`:

```json
{
  "success": true,
  "data": { "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271", "status": "processing", "completed": false },
  "timestamp": "2026-05-28T18:04:12"
}
```

A successful result is final when `data.completed` is `true`. Most endpoints pair that with `status: "completed"`; an endpoint may document other successful terminal values, such as People Search's `exhausted` and `stale`. When a successful payload includes `data.completed`, `false` means keep polling and `true` means stop, regardless of whether the HTTP status is `200` or `202`. Terminal failures may instead arrive as an error envelope or non-retriable non-2xx response without a true completed flag; those also stop the request. Transient transport/status-infrastructure responses remain retryable when the endpoint documents a retry policy. Interpret `data.status` using that endpoint's status table. See [Async requests](https://api.nyne.ai/documentation/async.md) for the full lifecycle, poll cadence, and webhook callbacks.

## Confidence and scoring

Search can rank its matches. Opt in with `profile_scoring` to attach a query-fit score to each result:

```bash
curl -X POST https://api.nyne.ai/person/search \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "query": "VP of Product at Acme", "profile_scoring": true }'
```

```json
{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "completed",
    "completed": true,
    "results": [
      { "displayname": "Jane Doe", "headline": "VP of Product at Acme", "probability": 0.94 },
      { "displayname": "Jane Doe", "headline": "Analyst at Globex", "probability": 0.42 }
    ]
  },
  "timestamp": "2026-05-28T18:04:39"
}
```

Pick a confidence bar that fits your use case and threshold on `probability` rather than blindly trusting the top match - a high bar for automated writes, a lower one for human review. Be aware of the limit: `probability` is the only confidence number the API exposes. There are no per-field confidence values, so a returned field is present or it is not.

## Public response contract

Treat the fields and status values documented for each endpoint as the complete response contract. Operational metadata and source attribution are not part of that contract and must not be required by client code.

Use stable `error.code` values for branching and documented response fields for data access. Human messages are for display or logs and can change wording, so do not parse implementation details from a `message`.

## Partial and failed results

A match can be partial. Fields that could not be resolved simply do not appear, or come back `null` - a profile with a name and company but no phone is a normal, useful result. Do not assume any single field will be present.

When a request finds nothing at all it presents as a terminal failure: `status: "failed"` with `completed: true`. A clean no-match commonly reads as a `404` on the underlying request:

```json
{
  "success": true,
  "data": {
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "status": "failed",
    "completed": true,
    "error": "No match found for the supplied identifiers."
  },
  "timestamp": "2026-05-28T18:04:39"
}
```

Accept partial matches that clear your confidence bar. A transient `failed` or a `503` is retryable with backoff; a clean no-match (nothing exists for those identifiers) is not - retrying just burns calls. See [Rate limits](https://api.nyne.ai/documentation/rate-limits.md) for the full retryable error taxonomy.

## Report bad data

Found something wrong or stale in a result? Close the loop with `POST /person/enrichment/feedback`. It is synchronous and returns `200` right away - pass the `request_id` from the result you are correcting and a non-empty `comments` string:

```bash
curl -X POST https://api.nyne.ai/person/enrichment/feedback \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
    "comments": "The current company is out of date; she left Acme in early 2026."
  }'
```

## What's next

- [Async requests](https://api.nyne.ai/documentation/async.md) - the full submit, poll, and callback lifecycle behind every 202.
- [Rate limits](https://api.nyne.ai/documentation/rate-limits.md) - which errors are retryable, and how to back off cleanly.
- [Effective requests](https://api.nyne.ai/documentation/effective-requests.md) - send stronger identifiers to get fuller, higher-confidence matches.
- [Your first request](https://api.nyne.ai/documentation/first-request.md) - the end-to-end walkthrough this page's rules apply to.
