# Simulation API
> Predict how a person would respond to any question using AI-powered behavioral modeling with sentiment, conviction, and confidence analysis
**Base URL:** `https://api.nyne.ai`
**Endpoint:** `https://api.nyne.ai/person/simulation`

---

## Overview
The Simulation API predicts how a person would respond to any question by combining comprehensive intelligence data with AI-powered behavioral modeling. Provide a question plus a person identifier -- email address, phone number, social media URL(s), or a name with company/city -- and get back a structured prediction including sentiment analysis, conviction level, confidence scoring, key drivers, and a detailed simulated response.

The processing pipeline works in four stages: (1) question analysis to determine relevant data sources, (2) enrichment data collection with question-aware prioritization, (3) parallel behavioral analysis of interaction patterns, interests, and relationships, and (4) simulation synthesis that combines all intelligence to predict the response. When insufficient data is available, the API returns an explicit insufficient-data indicator rather than a low-quality guess.

Delivery is asynchronous: submit a POST request, receive a request_id, then poll with GET or register a callback_url to be notified when results are ready. Typical processing time is 2-5 minutes. If an identical simulation (same person + same question) was recently processed, the cached result is returned immediately with a 200 status.
### What You Get
- **Sentiment Analysis:** Predicted stance toward the question topic (positive, negative, neutral, mixed, unknown)- **Short Answer:** A concise 1-2 sentence prediction of the person's likely response- **Conviction Level:** How strongly the person would hold their position (strong, moderate, mild, uncertain)- **Confidence Score:** AI confidence in the prediction accuracy (high, medium, low) with reasoning- **Key Drivers:** Factors that would most influence the person's response- **Simulated Response:** A detailed, in-character response written as if the person were answering the question themselves
## 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

- **Simulation:** 122 credits per completed simulation (includes enrichment, deep research, and AI behavioral modeling)
> Credits are only charged when the simulation completes successfully. Typical cost is approximately 122 credits per request including deep research. A minimum balance of 10 credits is required to submit a request.
---

## POST /person/simulationSubmit a question and person identifier to simulate how that person would respond, with sentiment analysis and confidence scoring.
### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `question` | string | Yes | The question to simulate a response for (max 1000 characters) |
| `email` | string | No | Email address of the person |
| `phone` | string | No | Phone number (E.164 format preferred, e.g., +15551234567) |
| `social_media_url` | string | string[] | No | LinkedIn, Twitter/X, or Instagram profile URL. Pass a single URL string or an array of up to 3 URLs (one per platform) for faster results. |
| `name` | string | No | Full name to search for (requires company or city for disambiguation) |
| `company` | string | No | Company name to help disambiguate name-based searches. Can be combined with city for better accuracy. |
| `city` | string | No | City/location to help disambiguate name-based searches (e.g., "San Francisco", "NYC"). Can be combined with company for better accuracy. |
| `callback_url` | string | No | URL to receive results when processing completes |

> **Required:** In addition to the required question, you must provide at least one of: email, phone, social_media_url, OR name with at least one of company or city. For best results with common names, provide both company and city.
### Request Examples

**With Advanced Features:**

```json
{
  "question": "Would you be interested in switching to a new CRM platform?",
  "email": "ceo@company.com",
  "callback_url": "https://yourapp.com/webhook/simulation"
}
```

**Basic Request:**

```json
{
  "question": "What do you think about remote work policies?",
  "social_media_url": "https://linkedin.com/in/ceo"
}
```

**Name-Based Lookup:**

```json
{
  "question": "How do you feel about AI in the workplace?",
  "name": "John Smith",
  "company": "Acme Corp",
  "city": "San Francisco"
}
```
When using name-based search, provide at least the name plus either company or city (or both) for best results. Both company and city together yield the best disambiguation for common names.
### Code Examples

**cURL:**

```bash
curl -X POST https://api.nyne.ai/person/simulation \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "Would you be interested in switching to a new CRM platform?",
    "email": "ceo@company.com",
    "callback_url": "https://yourapp.com/webhook/simulation"
  }'
```

**Python:**

```python
import requests
import json
import time

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

# Submit simulation request
data = {
    "question": "Would you be interested in switching to a new CRM platform?",
    "email": "ceo@company.com"
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
request_id = result["data"]["request_id"]
print(f"Request submitted: {request_id}")

# Poll for results
while True:
    time.sleep(5)
    status_response = requests.get(
        f"{url}?request_id={request_id}",
        headers=headers
    )
    status = status_response.json()
    current_status = status["data"]["status"]
    print(f"Status: {current_status}")

    if current_status == "completed":
        at_a_glance = status["data"]["result"]["at_a_glance"]
        print(f"Sentiment: {at_a_glance['sentiment']}")
        print(f"Confidence: {at_a_glance['confidence']}")
        print(f"Response: {status['data']['result']['simulated_response']}")
        break
    elif current_status == "failed":
        print("Simulation failed")
        break
```

**JavaScript:**

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

const data = {
    question: "Would you be interested in switching to a new CRM platform?",
    email: "ceo@company.com"
};

// Submit simulation request
fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
    const requestId = result.data.request_id;
    console.log("Request submitted:", requestId);

    // Poll for results
    const poll = setInterval(() => {
        fetch(`${url}?request_id=${requestId}`, { headers })
        .then(r => r.json())
        .then(status => {
            console.log("Status:", status.data.status);
            if (status.data.status === "completed") {
                clearInterval(poll);
                const glance = status.data.result.at_a_glance;
                console.log("Sentiment:", glance.sentiment);
                console.log("Confidence:", glance.confidence);
                console.log("Response:", status.data.result.simulated_response);
            } else if (status.data.status === "failed") {
                clearInterval(poll);
                console.error("Simulation failed");
            }
        });
    }, 5000);
})
.catch(error => console.error("Error:", error));
```

**PHP:**

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

$data = [
    "question" => "Would you be interested in switching to a new CRM platform?",
    "email" => "ceo@company.com"
];

// Submit simulation request
$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);
$requestId = $result["data"]["request_id"];
echo "Request submitted: " . $requestId . "\n";
curl_close($ch);

// Poll for results
while (true) {
    sleep(5);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url . "?request_id=" . $requestId);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $statusResponse = curl_exec($ch);
    $status = json_decode($statusResponse, true);
    $currentStatus = $status["data"]["status"];
    echo "Status: " . $currentStatus . "\n";
    curl_close($ch);

    if ($currentStatus === "completed") {
        $glance = $status["data"]["result"]["at_a_glance"];
        echo "Sentiment: " . $glance["sentiment"] . "\n";
        echo "Confidence: " . $glance["confidence"] . "\n";
        echo "Response: " . $status["data"]["result"]["simulated_response"] . "\n";
        break;
    } elseif ($currentStatus === "failed") {
        echo "Simulation failed\n";
        break;
    }
}
?>
```

### Response Codes

| Code | Description |
|------|-------------|
| 202 | Simulation request queued for processing |
| 200 | Cached result returned immediately (identical person + question recently processed) |
| 400 | Invalid or missing request parameters |
| 401 | Invalid API credentials |
| 402 | Insufficient credits (minimum 10 credits required; typical request costs ~122 credits) |
| 403 | No active subscription or simulation not available on plan |
| 429 | Rate limit exceeded |

### Response Example

```json
{
  "success": true,
  "data": {
    "request_id": "sim_a1b2c3d4e5f6...",
    "status": "pending",
    "message": "Simulation request queued for processing. Use GET with request_id to check status.",
    "created_on": "2025-01-15T10:30:00"
  },
  "timestamp": "2025-01-15T10:30:00Z"
}
```

---

## GET /person/simulation
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/simulation?request_id=sim_a1b2c3d4e5f6
```

### Response Codes

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

### Response Example

```json
{
  "success": true,
  "data": {
    "request_id": "sim_a1b2c3d4e5f6...",
    "status": "completed",
    "completed": true,
    "result": {
      "at_a_glance": {
        "sentiment": "positive",
        "short_answer": "Likely receptive to a new CRM if it solves their current pain points around reporting and integrations.",
        "conviction_level": "moderate",
        "confidence": "high",
        "confidence_reason": "Strong signal from career history in SaaS, social posts about CRM frustrations, and technology-forward following patterns.",
        "is_sufficient_signal": true,
        "key_drivers": [
          "History of adopting new SaaS tools early",
          "Recent social posts expressing frustration with current CRM reporting",
          "Follows multiple CRM competitors and sales tech influencers",
          "Career focus on operational efficiency and data-driven decisions"
        ]
      },
      "simulated_response": "I'd definitely be open to hearing about it. We've been frustrated with our current setup -- especially the reporting limitations and the lack of native integrations with our marketing stack. If your platform can show me better pipeline visibility and reduce the manual data entry my team deals with, I'd be interested in a demo. That said, migration cost is always a concern, so I'd want to understand the transition plan and how long until we're fully operational.",
      "raw_markdown": "## Sentiment\npositive\n\n## Short Answer\nLikely receptive to a new CRM if it solves their current pain points around reporting and integrations.\n\n## Conviction Level\nmoderate\n\n## Confidence\nhigh\n\n## Key Drivers\n- History of adopting new SaaS tools early\n- Recent social posts expressing frustration with current CRM reporting\n- Follows multiple CRM competitors and sales tech influencers\n- Career focus on operational efficiency and data-driven decisions\n\n## Simulated Response\nI'd definitely be open to hearing about it..."
    },
    "created_on": "2025-01-15T10:30:00",
    "completed_on": "2025-01-15T10:33:00"
  },
  "timestamp": "2025-01-15T10:33:00Z"
}
```

---

## Response Format

All API responses follow a consistent JSON format. All fields in enrichment results are **optional** and only included when data is available:
- The at_a_glance object is always present in completed results and contains all structured fields- The sentiment field is one of: positive, negative, neutral, mixed, unknown- The conviction_level field is one of: strong, moderate, mild, uncertain- The confidence field is one of: high, medium, low- The is_sufficient_signal field is always a boolean (true/false)- The key_drivers array may be empty when is_sufficient_signal is false- The simulated_response is a plain-text in-character response- The raw_markdown field contains the full simulation output in markdown format for custom parsing
---

## Error Codes

| HTTP Code | Error Code | Description |
|-----------|------------|-------------|
| 400 | `INVALID_PARAMETERS` | Missing or invalid request parameters |
| 400 | `MISSING_PARAMETER` | Required parameter not provided (e.g., missing question) |
| 401 | `AUTHENTICATION_FAILED` | Invalid or missing API credentials |
| 402 | `INSUFFICIENT_CREDITS` | Not enough credits (minimum 10 credits required; typical request costs ~122 credits including deep research) |
| 403 | `NO_ACTIVE_SUBSCRIPTION` | No active subscription found |
| 403 | `PRODUCT_NOT_AVAILABLE` | Simulation not available on your plan |
| 403 | `ACCESS_DENIED` | Not authorized to access this resource |
| 404 | `NOT_FOUND` | Request not found |
| 429 | `RATE_LIMIT_EXCEEDED` | Too many requests, please slow down |
| 500 | `QUEUE_ERROR` | Failed to queue request for processing |

---

## 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: 1s, 5s, 15s, 1m, 5m- 30-second timeout per request- Your endpoint should return HTTP 2xx for success
Your callback endpoint should respond with HTTP 200-299. Any other code triggers a retry.

### Callback Payload Example

```json
POST your_callback_url
Content-Type: application/json

{
  "request_id": "sim_a1b2c3d4e5f6...",
  "status": "completed",
  "completed": true,
  "result": {
    "at_a_glance": {
      "sentiment": "positive",
      "short_answer": "Likely receptive to a new CRM if it solves their current pain points.",
      "conviction_level": "moderate",
      "confidence": "high",
      "confidence_reason": "Strong signal from career history and social activity.",
      "is_sufficient_signal": true,
      "key_drivers": [
        "History of adopting new SaaS tools early",
        "Recent social posts expressing CRM frustration"
      ]
    },
    "simulated_response": "I'd definitely be open to hearing about it...",
    "raw_markdown": "## Sentiment\npositive\n\n..."
  }
}
```

---

## Best Practices

Prioritize inputs in this order for best match rates:
1. **LinkedIn URL** (Best) - Provides the richest social signal for behavioral modeling. LinkedIn posts, career history, and network data significantly improve simulation accuracy.2. **Email Address** (Good) - Work emails typically perform better than personal emails. Enables full enrichment pipeline for comprehensive person data.3. **Multiple Social URLs** (Good) - Providing up to 3 social URLs (one per platform) enables parallel data fetching and reduces processing time.4. **Name + Company + City** (Fair) - Use when no direct identifier is available. Both company and city together yield the best disambiguation for common names.
> **Combining Inputs:** Providing a social_media_url alongside an email gives the simulation engine more behavioral signal to work with. The combination of structured career data and social activity patterns produces the most reliable predictions.
**Recommendation:** Whenever possible, provide a LinkedIn URL. If you have multiple social profiles, pass them as an array to enable parallel processing. For name-based lookups, always include both company and city for common names.
---

## Note for AI Agents
Simulation results include an is_sufficient_signal boolean in the at_a_glance object. AI agents should always check this field before acting on simulation results. When is_sufficient_signal is false, the prediction lacks enough data to be reliable - agents should treat the response as inconclusive rather than factual. Additionally, the confidence field (high/medium/low) and confidence_reason provide transparency into prediction quality. Automated workflows should set minimum confidence thresholds appropriate to their use case.
---

## Related APIs
- **Deep Research API** - Intelligence dossier used by simulation -> `https://api.nyne.ai/documentation/person/deep-research`
- **Person Enrichment API** - Structured person data -> `https://api.nyne.ai/documentation/person/enrichment`