# Person Enrichment

> Resolve a full person profile from one or more identifiers.

- **Endpoint:** `POST https://api.nyne.ai/person/enrichment`
- **Group:** Person APIs (https://api.nyne.ai/documentation/person.md)
- **Auth:** `X-API-Key` + `X-API-Secret` headers
- **Mode:** Asynchronous - submit returns `202 Accepted` with a `request_id`; poll `GET /person/enrichment?request_id=<request_id>` (same auth headers) until `status` is `completed`, or supply a `callback_url` to receive the result by webhook.
- **HTML version:** https://api.nyne.ai/documentation/person/enrichment

Submit one or more identifiers for a person (email, phone, social profile URL, or name). The service queues an asynchronous job that runs a multi-provider waterfall and fans out child jobs (newsfeed, social profiles, person events), then returns the merged, sanitized profile. At least one of `email`, `phone`, `social_media_url`, or `name` is required - a LinkedIn URL is the strongest input, followed by email, then phone. Results are polled at the status endpoint, or delivered to a `callback_url` when supplied. The completed `result` includes a derived `classifications` object (`seniority`, `job_functions`, `employment_types`, `academic_qualifications`) when at least one bucket has labels; a `probability` match-confidence field appears only when the request set `probability_score: true`.

## Authentication

All `/person/*` and `/company/*` endpoints authenticate with an API key and secret sent as HTTP headers on every request: `X-API-Key` and `X-API-Secret`. Create keys from your Nyne dashboard and keep the secret server-side. Rate limits: 100 requests/minute, 1,000 requests/hour. Full guide: https://api.nyne.ai/documentation/authentication.md

## Parameters

| Name | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `email` | string | no | Validated for format. | "jane.doe@acme.com" |
| `phone` | string | no | Must normalize to a US 10-digit number or an international E.164 number. | "+1-555-123-4567" |
| `social_media_url` | string | no | Profile URL. | "https://linkedin.com/in/janedoe" |
| `name` | string | no | Person's full name. At least one identifier (email/phone/url/name) is required. | "Jane Doe" |
| `company` | string | no | Employer; aids matching. | "Acme" |
| `city` | string | no | Location-based disambiguation for name lookups (max 100 chars). Common city abbreviations are understood. | "Austin" |
| `callback_url` | string | no | If set, results are POSTed here. Must be a valid HTTP(S) URL on an allowed host when a callback allow-list is configured. | "https://hooks.example.com/enrichment" |
| `newsfeed` | array \| string | no | Sources to also pull: any of `linkedin`, `twitter`, `instagram`, `github`, `facebook`, or the literal `"all"` (cannot be mixed with named sources). | ["linkedin", "github"] |
| `ai_enhanced_search` | boolean | no | Enable AI-assisted search expansion. | true |
| `strict_email_check` | boolean | no | Require stricter email-to-identity confirmation. | false |
| `lite_enrich` | boolean | no | Bill against the `person_enrichment_lite` credit bucket and return a reduced field set. | false |
| `probability_score` | boolean | no | Opt in to match-probability scoring: the result carries a `probability` field (`high`/`medium`/`low`) and medium/low-confidence LinkedIn matches become eligible. Without the opt-in only high-confidence matches are used and no `probability` field is returned. Automated systems should not gate decisions on this score alone. | false |
| `required_fields` | array | no | Field names the result must contain to count as a match (case-insensitive). Supported: `firstname`, `lastname`, `email`, `phone`, `current_company`, `current_title`, `linkedin`, `twitter`, `instagram`, `facebook`, `github`. With `lite_enrich` only `firstname`, `lastname`, `current_company`, `current_title`, `linkedin` are available. | ["current_title", "linkedin"] |

## Polling for the result

The submit returns `202 Accepted` with a `request_id`. Poll the same path until `status` is `completed` (results stay available afterwards), or pass a `callback_url` on the submit to receive the completed result by webhook instead:

```bash
curl "https://api.nyne.ai/person/enrichment?request_id=<request_id>" \
  -H "X-API-Key: nyne_live_a17f…3c9b" \
  -H "X-API-Secret: nyne_sec_••••••••"
```

## Credit usage

| Item | Credits | Condition |
| --- | --- | --- |
| Person Enrichment | - | Charged only on a meaningful result (provider or cache hit) |
| Lite Enrichment | - | lite_enrich: true - billed against the person_enrichment_lite bucket |
| No match | 0 | Empty results never burn credits |
| Cache hit | full | Cache hits are charged at the full bucket rate |

## Responses

| Code | Meaning |
| --- | --- |
| `202` | Enrichment queued - poll /person/enrichment with the returned request_id |
| `400` | Malformed JSON, missing identifiers, or an invalid field (e.g. invalid_newsfeed, invalid_required_fields - a field not available in lite mode) |
| `401` | Missing or invalid API credentials |
| `402` | insufficient_credits - no balance in the selected bucket |
| `403` | subscription_required or ip_not_allowed |
| `429` | rate_limit_exceeded |
| `503` | service_unavailable - backing store/queue unconfigured |

## Example request

### cURL

```bash
curl -X POST https://api.nyne.ai/person/enrichment \
  -H "X-API-Key: nyne_live_a17f…3c9b" \
  -H "X-API-Secret: nyne_sec_••••••••" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane.doe@acme.com",
    "name": "Jane Doe",
    "company": "Acme",
    "newsfeed": [
      "linkedin",
      "github"
    ],
    "ai_enhanced_search": true
  }'
```

### Python

```python
import requests

resp = requests.post(
    "https://api.nyne.ai/person/enrichment",
    headers={
        "X-API-Key": "nyne_live_a17f…3c9b",
        "X-API-Secret": "nyne_sec_••••••••",
    },
    json={
        "email": "jane.doe@acme.com",
        "name": "Jane Doe",
        "company": "Acme",
        "newsfeed": [
            "linkedin",
            "github",
        ],
        "ai_enhanced_search": True,
    },
)
data = resp.json()
print(data)
```

### Node

```javascript
const resp = await fetch("https://api.nyne.ai/person/enrichment", {
  method: "POST",
  headers: {
    "X-API-Key": "nyne_live_a17f…3c9b",
    "X-API-Secret": "nyne_sec_••••••••",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "jane.doe@acme.com",
    name: "Jane Doe",
    company: "Acme",
    newsfeed: [
      "linkedin",
      "github",
    ],
    ai_enhanced_search: true,
  }),
});
const data = await resp.json();
console.log(data);
```

### PHP

```php
<?php
$ch = curl_init("https://api.nyne.ai/person/enrichment");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "X-API-Key: nyne_live_a17f…3c9b",
    "X-API-Secret: nyne_sec_••••••••",
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "email" => "jane.doe@acme.com",
    "name" => "Jane Doe",
    "company" => "Acme",
    "newsfeed" => [
      "linkedin",
      "github",
    ],
    "ai_enhanced_search" => true,
  ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data);
```

## Example response

```json
{
  "request_id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4_1717000000_4271",
  "status": "completed",
  "completed": true,
  "result": {
    "displayname": "Jane Doe",
    "firstname": "Jane",
    "lastname": "Doe",
    "headline": "VP of Product at Acme",
    "location": "San Francisco, CA",
    "best_business_email": "jane.doe@acme.com",
    "best_work_email": "jane.doe@acme.com",
    "best_personal_email": "jane@gmail.com",
    "altemails": [
      "jane.doe@acme.com",
      "jane@example.com"
    ],
    "fullphone": [
      {
        "fullphone": "+1-555-123-4567",
        "phone_type": "mobile"
      }
    ],
    "social_profiles": {
      "linkedin": {
        "url": "https://linkedin.com/in/janedoe",
        "followers": 2847
      },
      "twitter": {
        "url": "https://x.com/janedoe",
        "followers": 1234
      }
    },
    "organizations": [
      {
        "name": "Acme",
        "title": "VP of Product",
        "is_current": true
      },
      {
        "name": "StartupXYZ",
        "title": "Product Manager",
        "is_current": false
      }
    ],
    "classifications": {
      "seniority": [
        "vp"
      ],
      "job_functions": [
        "product_management"
      ],
      "employment_types": [
        "full_time"
      ]
    },
    "total_experience_years": 12
  },
  "error": null,
  "created_on": "2026-01-15T10:34:21",
  "completed_on": "2026-01-15T10:35:00"
}
```

---

All documentation pages are available as Markdown by appending `.md` to their URL. Index: https://api.nyne.ai/llms.txt
