# Your first request

> Every Nyne.ai data endpoint speaks the same language: authenticate with a key and secret, submit a request, and read the result out of one uniform envelope. Learn the pattern once here with person enrichment, and the rest of the API works exactly the same way.

HTML version: https://api.nyne.ai/documentation/first-request

The lifecycle every data endpoint follows: `POST /person/enrichment` -> `202 request_id` -> `GET ?request_id=` (poll) -> `200 result`.

## Before you start

You need two things: a **key and secret**, and the **base URL**.

- Sign in and open API keys in your dashboard, then click **Create key**. Copy the secret right away - it is shown only once. The full walkthrough is in the [Authentication guide](https://api.nyne.ai/documentation/authentication.md).
- Every request goes to `https://api.nyne.ai`. Send the key and secret as the `X-API-Key` and `X-API-Secret` headers, and always call from your backend so the secret never reaches a browser.

## Make a request

Submit one or more identifiers - here, just an email - to `POST /person/enrichment`:

```bash
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" }'
```

It returns `202 Accepted` right away. The work is not done - you get a `request_id` to poll with next:

```json
{
  "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"
}
```

## Poll for the result

Send a `GET` to the **same path** with the `request_id` until you get a `200` with `status` of `completed`. Enrichment typically finishes in well under a second, so your first poll often already returns the result - or pass a `callback_url` on the submit to get it by webhook and skip polling entirely.

```bash
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"
```

The completed poll returns the merged, sanitized profile, wrapped in the same envelope:

```json
{
  "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",
      "social_profiles": {
        "linkedin": { "url": "https://linkedin.com/in/janedoe", "followers": 2847 }
      },
      "organizations": [
        { "name": "Acme", "title": "VP of Product", "is_current": true }
      ],
      "total_experience_years": 12
    },
    "error": null,
    "created_on": "2026-05-28T18:04:11",
    "completed_on": "2026-05-28T18:04:39"
  },
  "timestamp": "2026-05-28T18:04:45"
}
```

## The response envelope

Every reply from the API - from any endpoint, success or failure - is wrapped in the same three keys: `success`, `data`, and `timestamp`. The envelope never changes; only what sits inside `data` does.

When something goes wrong, `success` is `false` and the detail moves under `error`. Branch on `error.code`, not on the human-readable `message` - the codes are stable, the messages are not:

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

Each `error.code` maps to an HTTP status you can also switch on:

| error.code | HTTP | Meaning |
| --- | --- | --- |
| missing_credentials | 401 | No key or secret was sent. |
| invalid_credentials | 401 | The key or secret is wrong or expired. |
| access_denied | 403 | The key lacks access to this product. |
| ip_not_allowed | 403 | The request came from an unlisted IP. |
| insufficient_credits | 402 | The workspace is out of credits. |
| rate_limit_exceeded | 429 | Too many requests. Back off and retry. |
| request_not_found | 404 | No request matches that request_id. |

## What you won't see

Nyne.ai draws on many underlying data sources, but you never see which one a given field came from. Provider and vendor identifiers are stripped from every response by design, so the profile you get back is clean, merged, and yours to use - with no source names, internal keys, or vendor fields to work around.

## What's next

- [Authentication](https://api.nyne.ai/documentation/authentication.md) - keys, secrets, IP locking, and rate limits in full.
- [Person Enrichment](https://api.nyne.ai/documentation/person/enrichment.md) - every parameter, response code, and field in the profile you just saw.
- [Person Search](https://api.nyne.ai/documentation/person/search.md) - find people by natural-language query instead of a known identifier.
- [MCP Quick Start](https://api.nyne.ai/documentation/mcp/quickstart.md) - wire Nyne.ai into Claude, ChatGPT, Cursor, and other AI clients.
