Skip to content

Researcher API

Run AI-scored personality assessments over HTTP and retrieve the scored results.

Authentication

Every request authenticates with an API key sent as a bearer token:

Authorization: Bearer <your-api-key>

Create keys in Settings → Researcher API Keys. Keys are tied to your account and carry its subscription tier:

  • Catalog endpoints (GET /inventory*) work with any valid key, on any tier.
  • Assessment creation, result export, and all batch endpoints require a Researcher subscription. A valid key on a lower tier gets 403 Forbidden.

AI runs are metered: by default they draw on your account's credit balance, or use your own stored provider key when you have one connected. A run that can't be paid for returns 402 with an explanation and an upgrade/connect URL.

Quickstart

From zero to a scored assessment in three calls:

# 1. Find an inventory (id is what you pass as inventoryId)
curl -s https://ipsyc.io/api/v1/inventory \
  -H "Authorization: Bearer $IPSYC_API_KEY"

# 2. Run an assessment: an AI model answers the inventory, we score it
curl -s -X POST https://ipsyc.io/api/v1/assessment \
  -H "Authorization: Bearer $IPSYC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Rate yourself on a 1-5 Likert scale for each of the following statements.",
    "model": "qwen/qwen3.7-flash",
    "inventoryId": "bfi10"
  }'

# 3. Fetch the stored result later by its id
curl -s https://ipsyc.io/api/v1/assessment/<id> \
  -H "Authorization: Bearer $IPSYC_API_KEY"

A successful run returns 201 Created with the session id, the scored scales (and subscales, where the inventory defines them), and any scoring warnings.

POST /api/v1/assessment

The request body has four fields:

{
  "prompt":      string,  // required, 1–5000 chars — instruction for the model
  "model":       string,  // required, 1–200 chars — e.g. "qwen/qwen3.7-flash"
  "inventoryId": string,  // required, 1–100 chars — an id from GET /inventory
  "provider":    "openai" | "huggingface" | "openrouter"  // optional; derived from the model when omitted
}

Your prompt is sent to the model together with the inventory's item list, so a short instruction like the default above is enough — you do not need to enumerate items yourself. The model's answers are scored server-side against the inventory's scoring key.

Responses

201 Created
{
  "data": {
    "id": "…",            // session id — use with GET /assessment/{id}
    "inventoryId": "bfi10",
    "type": "ai",
    "aiModel": "gpt-4o-mini",
    "timestamp": "…",
    "results": { "scales": { … }, "subscales": { … } },
    "warnings": []
  }
}

Errors

400  Invalid JSON body or schema violation (error = per-field messages)
     Unknown inventoryId: the body names the code, lists the
     supported inventories, and points at GET /inventory
401  Missing/invalid API key            (WWW-Authenticate: Bearer)
402  Run can't be paid for: no stored provider key, no credits, or
     tier denies the run (error explains; includes upgradeUrl where apt)
403  Key valid but account is not on the Researcher tier
422  Model response failed validation (e.g. items missing from the answer)
429  Rate limit exceeded (20 assessments/min per key)

Endpoints

GET  /api/v1/health                       any tier
GET  /api/v1/inventory                    any tier   ?offset&limit&search
GET  /api/v1/inventory/{id}               any tier
GET  /api/v1/inventory/{id}/items         any tier   ?offset&limit
GET  /api/v1/inventory/{id}/scales        any tier   ?offset&limit
GET  /api/v1/assessment                   any tier   ?offset&limit   (your runs)
POST /api/v1/assessment                   researcher
GET  /api/v1/assessment/{id}              any tier
GET  /api/v1/assessment/{id}/export/{format}   researcher   format: csv|json
GET  /api/v1/batch                        researcher ?offset&limit
POST /api/v1/batch                        researcher (≤10 models, ≤5 inventories)
GET  /api/v1/batch/{id}                   researcher (batch status + items)

PDF export is not yet available via the API (use the web interface); csv and json are. List endpoints return { data: [...], total, offset, limit }; single resources return { data: {...} }; errors return { error: "…" }. Pagination defaults: offset=0, limit=25 (max 100).

OpenAPI spec

The complete machine-readable spec (OpenAPI 3.0) is served at /api/v1/openapi — load it into Swagger UI, Insomnia, or any OpenAPI client to generate a client for your language.