# 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

Responses contain the documented Nyne.ai fields only. Operational metadata and source attribution are not part of the public response contract. Parse only the fields documented for the endpoint, and do not use undocumented metadata for application logic.

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