Base URL: https://app.simsurveys.com/api/v1
Authentication
All API requests are authenticated using Bearer tokens. API keys are managed from the API Dashboard.
Authorization: Bearer sk_live_abc123...
- Keys are 72 characters long and begin with
sk_live_. - Keys are shown once at creation and cannot be retrieved again. Store them securely.
- A maximum of 10 active keys may exist per account at a time.
- Keys can optionally have an expiration date (30, 60, 90, 180, or 365 days).
Key Security
- Only a cryptographic hash of your key is stored. SimSurveys cannot recover your raw key.
- Keys are verified using timing-safe comparison to prevent timing attacks.
- Revoked or expired keys are immediately rejected.
Rate Limiting
Each API key has a configurable rate limit (default: 60 requests per minute, range: 1–1,000).
Every response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the current window |
X-RateLimit-Remaining |
Requests remaining in the current window |
X-RateLimit-Reset |
Unix timestamp (ms) when the window resets |
When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header (in seconds).
Error Format
All errors follow a consistent structure:
{ "error": { "type": "validation_error", "message": "A human-readable description of the error." } }
Error Types
| Type | HTTP Status | Description |
|---|---|---|
authentication_error |
401 | Missing, invalid, or expired API key |
permission_error |
403 | Key lacks required scope, or account doesn’t have Oracle access |
validation_error |
400 | Invalid request body or parameters |
upstream_error |
502 | The prediction model failed to return a result |
internal_error |
500 | Unexpected server error |
Endpoints
Create Prediction
Runs a single prediction against the specified model. The model returns a probability distribution over the provided answer options.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
model_type |
string | Yes | One of: consumer, hcp, social |
question |
string | Yes | The survey question text (max 5,000 characters) |
options |
string[] | Yes | Array of 2–20 answer options |
context |
string | No | Survey context or description. Consumer model only. |
demographics |
object | No | Key-value pairs of demographic attributes (e.g., {"age": "25-34"}). Consumer and social models only. |
medical_specialty |
string | No | Medical specialty for HCP targeting (e.g., "Cardiology"). HCP model only. |
response_history |
object | No | A previous question-answer pair for context. Must contain question (string) and answer (string). All models. |
Model-Specific Parameters
| Parameter | consumer |
hcp |
social |
|---|---|---|---|
context |
Accepted | Not accepted | Not accepted |
demographics |
Accepted | Not accepted | Accepted |
medical_specialty |
Not accepted | Accepted | Not accepted |
response_history |
Accepted | Accepted | Accepted |
Example Request
curl -X POST https://app.simsurveys.com/api/v1/oracle/predict \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "model_type": "consumer", "question": "Which brand do you prefer for running shoes?", "options": ["Nike", "Adidas", "New Balance", "Puma"], "context": "Brand awareness study among active runners", "demographics": { "age": "25-34", "gender": "Male", "region": "Northeast US" } }'
Example Response
{ "id": "pred_a1b2c3d4e5f6a1b2c3d4e5f6", "object": "oracle.prediction", "created": 1707854400, "model": "consumer", "result": { "labeled_distribution": { "Nike": 0.42, "Adidas": 0.28, "New Balance": 0.19, "Puma": 0.11 }, "num_choices": 4 } }
Response Fields
| Field | Type | Description |
|---|---|---|
id |
string | Unique prediction identifier (prefixed with pred_) |
object |
string | Always "oracle.prediction" |
created |
integer | Unix timestamp of when the prediction was generated |
model |
string | The model type used (consumer, hcp, or social) |
result.labeled_distribution |
object | A map of each option to its predicted probability (values sum to ~1.0) |
result.num_choices |
integer | Number of answer options |
Create Batch Prediction
Run multiple predictions in a single request. Predictions are executed concurrently. Maximum batch size is 10.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
requests |
array | Yes | Array of 1–10 prediction request objects (same schema as the single predict endpoint) |
Example Request
curl -X POST https://app.simsurveys.com/api/v1/oracle/predict/batch \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "requests": [ { "model_type": "consumer", "question": "Which brand do you prefer?", "options": ["Nike", "Adidas", "Puma"] }, { "model_type": "consumer", "question": "How often do you exercise?", "options": ["Daily", "2-3 times a week", "Weekly", "Rarely"] } ] }'
Example Response
{ "object": "list", "data": [ { "id": "pred_a1b2c3d4e5f6a1b2c3d4e5f6", "object": "oracle.prediction", "created": 1707854400, "model": "consumer", "result": { "labeled_distribution": { "Nike": 0.45, "Adidas": 0.35, "Puma": 0.20 }, "num_choices": 3 } }, { "id": "pred_f6e5d4c3b2a1f6e5d4c3b2a1", "object": "oracle.prediction", "created": 1707854400, "model": "consumer", "result": { "labeled_distribution": { "Daily": 0.15, "2-3 times a week": 0.35, "Weekly": 0.30, "Rarely": 0.20 }, "num_choices": 4 } } ] }
Partial failures: If an individual prediction within the batch fails, it returns an error object in its position instead of a result. The batch request itself will still return 200 — check each item in data for individual errors.
Code Examples
Python
# Single prediction import requests API_KEY = "sk_live_your_key_here" BASE_URL = "https://app.simsurveys.com/api/v1" response = requests.post( f"{BASE_URL}/oracle/predict", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "model_type": "consumer", "question": "Which brand do you prefer?", "options": ["Nike", "Adidas", "Puma"], "demographics": {"age": "25-34", "gender": "Female"}, }, ) data = response.json() print(data["result"]["labeled_distribution"]) # {'Nike': 0.45, 'Adidas': 0.35, 'Puma': 0.20}
JavaScript / Node.js
const API_KEY = "sk_live_your_key_here"; const BASE_URL = "https://app.simsurveys.com/api/v1"; const response = await fetch(`${BASE_URL}/oracle/predict`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ model_type: "consumer", question: "Which brand do you prefer?", options: ["Nike", "Adidas", "Puma"], demographics: { age: "25-34", gender: "Female" }, }), }); const data = await response.json(); console.log(data.result.labeled_distribution); // { Nike: 0.45, Adidas: 0.35, Puma: 0.20 }
Python — Batch Prediction
import requests API_KEY = "sk_live_your_key_here" BASE_URL = "https://app.simsurveys.com/api/v1" response = requests.post( f"{BASE_URL}/oracle/predict/batch", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "requests": [ { "model_type": "consumer", "question": "Which brand do you prefer?", "options": ["Nike", "Adidas", "Puma"], }, { "model_type": "hcp", "question": "Which treatment do you prescribe most?", "options": ["Drug A", "Drug B", "Drug C"], "medical_specialty": "Cardiology", }, ] }, ) data = response.json() for prediction in data["data"]: if "error" in prediction: print(f"Error: {prediction['error']['message']}") else: print(f"{prediction['model']}: {prediction['result']['labeled_distribution']}")
Python — HCP Model with Response History
import requests API_KEY = "sk_live_your_key_here" BASE_URL = "https://app.simsurveys.com/api/v1" response = requests.post( f"{BASE_URL}/oracle/predict", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", }, json={ "model_type": "hcp", "question": "Would you switch this patient to the new therapy?", "options": [ "Yes, immediately", "Yes, at next visit", "No, stay current", "Need more data", ], "medical_specialty": "Oncology", "response_history": { "question": "How satisfied are you with current treatment outcomes?", "answer": "Somewhat dissatisfied", }, }, ) data = response.json() print(data["result"]["labeled_distribution"])
JavaScript — Handling Rate Limits
async function predictWithRetry(payload, maxRetries = 3) { const API_KEY = "sk_live_your_key_here"; const BASE_URL = "https://app.simsurveys.com/api/v1"; for (let attempt = 0; attempt <= maxRetries; attempt++) { const response = await fetch(`${BASE_URL}/oracle/predict`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); if (response.status === 429) { const retryAfter = parseInt(response.headers.get("Retry-After") || "5"); console.log(`Rate limited. Retrying in ${retryAfter}s...`); await new Promise(r => setTimeout(r, retryAfter * 1000)); continue; } return await response.json(); } throw new Error("Max retries exceeded"); }
Models
Consumer Model (consumer)
General consumer survey simulation. Best for market research, brand tracking, product concept testing, and general population surveys.
Supported parameters: context, demographics, response_history
HCP Model (hcp)
Healthcare professional survey simulation. Designed for physician and healthcare provider research, including treatment preferences, prescribing behavior, and medical decision-making studies.
Supported parameters: medical_specialty, response_history
Social Model (social)
Social research simulation. Optimized for social attitudes, behavioral research, and opinion polling.
Supported parameters: demographics, response_history
API Key Management
API keys are managed through the API Dashboard or programmatically via the management endpoints below. Management endpoints require session authentication (logged-in user), not Bearer token auth.
List Keys
Returns all API keys for your account.
Response
{ "keys": [ { "id": "clx1234567890", "name": "Production", "keyPrefix": "sk_live_a1b2c3d4", "scopes": ["oracle:predict"], "status": "active", "rateLimit": 60, "lastUsedAt": "2026-02-12T15:30:00.000Z", "totalRequests": 1250, "createdAt": "2026-01-15T10:00:00.000Z", "expiresAt": "2026-04-15T10:00:00.000Z", "revokedAt": null } ] }
Create Key
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | Yes | — | A descriptive name for the key |
expiresInDays |
number | No | No expiration | Days until expiration (e.g., 30, 60, 90, 180, 365) |
scopes |
string[] | No | ["oracle:predict"] |
Permission scopes |
rateLimit |
number | No | 60 | Requests per minute (1–1,000) |
Response
{ "id": "clx1234567890", "name": "Production", "keyPrefix": "sk_live_a1b2c3d4", "scopes": ["oracle:predict"], "status": "active", "rateLimit": 60, "createdAt": "2026-02-13T10:00:00.000Z", "rawKey": "sk_live_a1b2c3d4e5f6g7h8i9j0...z6a7b8", "warning": "Store this key securely. It cannot be retrieved again." }
Revoke Key
Permanently revokes an API key. This action cannot be undone.
Response
{ "success": true, "message": "Key revoked." }
Usage & Analytics
Get Usage Stats
Returns aggregated usage statistics for your account.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
days |
number | 30 | Number of days to report (1–90) |
keyId |
string | — | Filter usage to a specific API key |
Response
{ "totalRequests": 1250, "dailyCounts": [ { "date": "2026-02-01", "count": 42 }, { "date": "2026-02-02", "count": 38 } ], "byStatus": { "200": 1200, "400": 30, "502": 20 }, "avgLatencyMs": 245, "days": 30, "recentLogs": [ { "id": "log_abc123", "endpoint": "/api/v1/oracle/predict", "method": "POST", "statusCode": 200, "latencyMs": 312, "createdAt": "2026-02-13T14:22:00.000Z", "apiKeyId": "clx1234567890", "apiKey": { "name": "Production", "keyPrefix": "sk_live_a1b2c3d4" } } ] }
Limits & Constraints
| Constraint | Value |
|---|---|
| Max active API keys per account | 10 |
| Rate limit range | 1–1,000 requests/minute per key |
| Default rate limit | 60 requests/minute |
| Max batch size | 10 predictions per request |
| Max question length | 5,000 characters |
| Answer options per question | 2–20 |
| Usage reporting window | 1–90 days |
| Recent logs returned | Last 100 requests |
HTTP Status Codes
| Status | Meaning |
|---|---|
200 |
Success |
400 |
Bad request — invalid parameters or validation failure |
401 |
Unauthorized — missing, invalid, or expired API key |
403 |
Forbidden — insufficient scope or Oracle access not enabled |
404 |
Not found |
429 |
Too many requests — rate limit exceeded |
502 |
Bad gateway — upstream model prediction failed |
500 |
Internal server error |