API Reference

Oracle API Documentation

Programmatically run survey predictions against SimSurveys' proprietary consumer, HCP, and social models.

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

POST /api/v1/oracle/predict

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

POST /api/v1/oracle/predict/batch

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

GET /api/v1/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

POST /api/v1/keys

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

DELETE /api/v1/keys/{keyId}

Permanently revokes an API key. This action cannot be undone.

Response

{
  "success": true,
  "message": "Key revoked."
}

Usage & Analytics

Get Usage Stats

GET /api/v1/usage

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

Start building with the Oracle API.

Create an account and generate your first API key in minutes.