# Person Discover API
> Discover people based on keywords and criteria. Find potential leads, professionals, and contacts matching your search terms.
**Base URL:** `https://api.nyne.ai`
**Endpoint:** `https://api.nyne.ai/person/discover`

---

## Overview
The Person Discover API helps you find people matching specific keywords and location criteria. Provide keywords describing the type of people you're looking for (like "registered nurses" or "software engineers") and optionally specify a location to narrow your search. The API returns a list of matching profiles with contact information.

This is an asynchronous API. You submit a discovery request via POST and receive a request_id. Use the GET endpoint to poll for results, or provide a callback_url to receive results automatically when processing completes.
### What You Get
- **Profile Information:** Names, bios, and profile details for discovered people- **Social Profiles:** Links to social media profiles (Facebook, LinkedIn, and more)- **Profile Photos:** Profile pictures when available- **Contact Details:** Email addresses, phone numbers, and professional information when available
## Authentication

All requests require header authentication:

```
X-API-Key: YOUR_API_KEY
X-API-Secret: YOUR_API_SECRET
```

## Rate Limits

| Limit | Value |
|-------|-------|
| Per Minute | 60 requests |
| Per Hour | 1000 requests |
| Monthly | Varies by plan |

### Response Headers

Responses from endpoints that perform rate-limit checks include both legacy and standard rate-limit headers:

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Active per-minute or per-hour limit |
| `X-RateLimit-Remaining` | Remaining requests in the active window |
| `X-RateLimit-Reset` | Unix timestamp when the active window resets |
| `RateLimit-Limit` | Active per-minute or per-hour limit |
| `RateLimit-Remaining` | Remaining requests in the active window |
| `RateLimit-Reset` | Seconds until the active window resets |
| `Retry-After` | Seconds to wait before retrying; present on HTTP `429` rate-limit responses |

Monthly quota responses include quota-specific headers when available:

| Header | Description |
|--------|-------------|
| `X-Quota-Limit` | Monthly request or credit limit |
| `X-Quota-Used` | Amount used in the current billing cycle |
| `X-Quota-Remaining` | Amount remaining in the current billing cycle |
| `X-Quota-Reset` | Unix timestamp when the current billing cycle resets |

## Credit Usage

- **Discovery:** 1 credit per result returned from keyword-based people discovery
- **Enrichment:** 1 additional credit per successfully enriched result (only charged when contact details are found)
> Discovery credits are charged per result returned. Enrichment credits are only charged when the enrichment returns contact details. If no contact details are found for a result, the enrichment credit is not charged.
---

## POST /person/discoverStart a new person discovery request based on keywords and optional location criteria.
### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `keywords` | string | Yes | Keywords describing the people to find (3-500 characters). Example: &quot;registered nurses&quot;, &quot;software engineers&quot;, &quot;real estate agents&quot; |
| `location` | string | No | Geographic location to search within. Can be a state (e.g., &quot;California&quot;, &quot;CA&quot;), city (e.g., &quot;San Francisco&quot;), or city/state (e.g., &quot;Miami, FL&quot;). If not specified, searches all of the US. |
| `max_results` | integer | No | Maximum number of results to return (1-100) (default: `50`) |
| `callback_url` | string | No | URL to receive results when processing completes |

> **Required:** The keywords parameter is required.
### Request Examples

**With Advanced Features:**

```json
{
  "keywords": "registered nurses",
  "location": "California",
  "max_results": 50,
  "callback_url": "https://yourapp.com/webhook/discover"
}
```

**Basic Request:**

```json
{
  "keywords": "registered nurses",
  "location": "California"
}
```

### Code Examples

**cURL:**

```bash
curl -X POST https://api.nyne.ai/person/discover \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": "registered nurses",
    "location": "California"
  }'
```

**Python:**

```python
import requests
import json

url = "https://api.nyne.ai/person/discover"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "X-API-Secret": "YOUR_API_SECRET",
    "Content-Type": "application/json"
}

data = {
    "keywords": "registered nurses",
    "location": "California"
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
print(json.dumps(result, indent=2))
```

**JavaScript:**

```javascript
const url = "https://api.nyne.ai/person/discover";
const headers = {
    "X-API-Key": "YOUR_API_KEY",
    "X-API-Secret": "YOUR_API_SECRET",
    "Content-Type": "application/json"
};

const data = {
    keywords: "registered nurses",
    location: "California"
};

fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.error("Error:", error));
```

**PHP:**

```php
<?php
$url = "https://api.nyne.ai/person/discover";
$headers = [
    "X-API-Key: YOUR_API_KEY",
    "X-API-Secret: YOUR_API_SECRET",
    "Content-Type: application/json"
];

$data = [
    "keywords" => "registered nurses",
    "location" => "California"
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch);

echo json_encode($result, JSON_PRETTY_PRINT);
?>
```

### Response Codes

| Code | Description |
|------|-------------|
| 202 | Discovery request queued for processing |
| 400 | Invalid request parameters |
| 401 | Invalid API credentials |
| 402 | Insufficient credits |
| 429 | Rate limit exceeded |

### Response Example

```json
{
  "request_id": "a1b2c3d4e5f6...",
  "status": "queued",
  "message": "Person discover request queued for processing."
}
```

---

## GET /person/discover
Check the status of a request.

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `request_id` | string | Yes | The request_id returned from the POST request |

### Request Example

```
GET /person/discover?request_id=a1b2c3d4e5f6
```

### Response Codes

| Code | Description |
|------|-------------|
| 200 | Status and results retrieved successfully |
| 400 | Invalid request parameters |
| 401 | Invalid API credentials |
| 404 | Request ID not found |

### Response Example

```json
{
  "request_id": "a1b2c3d4e5f6...",
  "status": "completed",
  "keywords": "registered nurses",
  "location": "California",
  "created_on": "2024-01-15T10:30:00Z",
  "completed_on": "2024-01-15T10:31:45Z",
  "results_count": 50,
  "results": [
    {
      "displayname": "Sarah Johnson",
      "first_name": "Sarah",
      "last_name": "Johnson",
      "headline": "Registered Nurse at Kaiser Permanente",
      "altemails": ["sarah.johnson@email.com"],
      "fullphone": ["+1-555-0123"],
      "location": "San Francisco, CA",
      "social_profiles": {
        "facebook": {
          "url": "https://facebook.com/sarah.johnson",
          "photo_url": "https://..."
        },
        "linkedin": {
          "url": "https://linkedin.com/in/sarahjohnson"
        }
      },
      "work_history": [
        {
          "title": "Registered Nurse",
          "company": "Kaiser Permanente",
          "start_date": "2020-01"
        }
      ]
    }
  ]
}
```

---

## Response Format

All API responses follow a consistent JSON format. All fields in enrichment results are **optional** and only included when data is available:
- If a field has no data, it will be omitted from the response (not included as null or empty string)- The results array is always present &mdash; it will be an empty array if no matches were found- Status values: pending, searching, discovering, enriching, completed, failed- Contact details (emails, phone numbers, work history) are only included for results that were successfully enriched- Social profile objects are only included when at least one social profile was found
---

## Error Codes

| HTTP Code | Error Code | Description |
|-----------|------------|-------------|
| 400 | `missing_parameters` | Required parameter is missing (e.g., keywords) |
| 400 | `invalid_keywords` | Keywords must be a string (3-500 characters). Arrays or objects are not accepted. |
| 400 | `invalid_location` | Location must be a string. Arrays or objects are not accepted. |
| 400 | `invalid_callback_url` | Callback URL is not a valid HTTP/HTTPS URL |
| 401 | `authentication_error` | Invalid or missing API credentials |
| 402 | `insufficient_credits` | Not enough credits for the requested operation |
| 404 | `not_found` | Request ID not found |
| 429 | `rate_limit_exceeded` | Too many requests, please wait before retrying |
| 500 | `internal_error` | Server error, please retry or contact support |

---

## Callbacks

When you provide a `callback_url`, the API sends results to your endpoint via HTTP POST.

### Retry Policy- Maximum 5 retry attempts- Exponential backoff between retries- Your endpoint should return HTTP 2xx for success- Both completed and failed results are sent to your callback URL
Your callback endpoint should respond with HTTP 200-299. Any other code triggers a retry.

### Callback Payload Example

```json
{
  "request_id": "a1b2c3d4e5f6...",
  "status": "completed",
  "completed": true,
  "results_count": 50,
  "results": [ ... ]
}
```

---

## Best Practices

Prioritize inputs in this order for best match rates:
1. **Specific Keywords** (Best) - Focus keywords on the profession or role you're looking for. &quot;registered nurses&quot; or &quot;licensed electricians&quot; yields better results than generic terms like &quot;healthcare&quot; or &quot;workers&quot;.2. **Location Parameter** (Good) - Specify a location to narrow results to a geographic area. You can use states (&quot;California&quot;), cities (&quot;San Francisco&quot;), or city/state combinations (&quot;Miami, FL&quot;). Leave blank to search all of the US.3. **Callback URLs** (Good) - For production use, provide a callback_url to receive results asynchronously instead of polling the GET endpoint.
**Recommendation:** Use specific professional keywords combined with a location parameter for the most relevant results. Handle empty result sets gracefully by checking results_count before processing. Implement exponential backoff when receiving 429 rate limit errors.
---

## Note for AI Agents
The Person Discover API is asynchronous. After submitting a POST request, poll the GET endpoint with the returned request_id until the status is &quot;completed&quot; or &quot;failed&quot;. Alternatively, provide a callback_url to receive results automatically. Status values progress through: pending, searching, discovering, enriching, completed (or failed). Always check results_count before iterating over results.
---

## Related APIs
- **Person Search API** - Natural language contact search -> `https://api.nyne.ai/documentation/person/search`
- **Person Leads API** - AI-powered lead generation -> `https://api.nyne.ai/documentation/person/leads`
- **Person Enrichment API** - Enrich discovered contacts with full profiles -> `https://api.nyne.ai/documentation/person/enrichment`