API docs for agent research.
The Infrence API has one production endpoint — /v1/research — and a small surface around it.
Quickstart
- Sign up and grab your default API key from API keys.
- POST a question to
/v1/researchwith your bearer token. - Read the brief and citations from the response.
curl https://api.infrence.ai/v1/research \
-H 'Authorization: Bearer inf_live_…' \
-H 'Content-Type: application/json' \
-d '{
"question": "Compare the top vector databases",
"mode": "standard"
}'Authentication
All /v1/* endpoints take a bearer token: Authorization: Bearer inf_live_…. Keys are issued from the dashboard. Reset or revoke at any time.
POST /v1/research
Request body
{
"question": "string",
"mode": "lite|standard|pro|max",
"max_credits": 65,
"max_wallclock_secs": 240,
"response_schema": {},
"include_sources": true,
"async": false,
"webhook_url": null
}Only question is required. mode defaults to standard. max_credits is required for mode=max.
Response (sync)
{
"id": "9b0a…",
"status": "succeeded",
"question": "Compare the top vector databases",
"brief": "Pinecone, Weaviate, and Qdrant lead the hosted-vector market…",
"typed": null,
"sources": [
{ "url": "https://…", "title": "…", "domain": "…", "summary": "…" }
],
"credits_charged": 65,
"latency_ms": 14480,
"created_at": "2026-05-04T10:11:12Z",
"completed_at": "2026-05-04T10:11:26Z"
}Response (async, 202)
{
"id": "9b0a…",
"status": "pending",
"status_url": "https://api.infrence.ai/v1/research/9b0a…",
"events_url": "https://api.infrence.ai/v1/research/9b0a…/events"
}Modes
| Mode | Credits | Max cost | Wallclock | Sources |
|---|---|---|---|---|
| Lite | 20 | $0.20 | 90s | 5 |
| Standard | 65 | $0.65 | 240s | 20 |
| Pro | 245 | $2.45 | 480s | 60 |
| Max | metered | your max_credits | 900s | 120 |
JSON Schema mode
Pass any JSON Schema in response_schema. The brief is re-cast into a typed object that conforms to the schema. If validation fails, your credits are refunded.
"response_schema": {
"type": "object",
"properties": {
"competitors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"url": { "type": "string" },
"pricing": { "type": "string" }
},
"required": ["name", "url"]
}
}
},
"required": ["competitors"]
}Async, webhooks, cancel
Long jobs return 202 + an id. The async path is taken when async=true, when a webhook_url is set, or when the effective max_wallclock_secs is greater than 30 — which covers every fixed-price mode at its default budget. Poll GET /v1/research/{id} or stream events from GET /v1/research/{id}/events (SSE). Cancel with DELETE /v1/research/{id} — the unspent reservation is refunded.
Idempotency
Pass Idempotency-Key: <your-key>. Repeating the same key within 24h returns the original job instead of running a new one — safe to retry from a flaky client.
Errors
400Invalid request body or impossible budget.401Missing or revoked API key.402Insufficient credits. Top up or upgrade.404Unknown job id (or owned by another user).5xxInternal error; the job is auto-refunded.Code samples
cURL
curl https://api.infrence.ai/v1/research \
-H 'Authorization: Bearer inf_live_…' \
-H 'Content-Type: application/json' \
-d '{
"question": "Compare the top vector databases",
"mode": "standard"
}'JavaScript
const res = await fetch('https://api.infrence.ai/v1/research', {
method: 'POST',
headers: {
'Authorization': 'Bearer inf_live_…',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"question": "Compare the top vector databases",
"mode": "standard"
}),
});
const data = await res.json();Python
import requests
res = requests.post(
'https://api.infrence.ai/v1/research',
headers={'Authorization': 'Bearer inf_live_…'},
json={
'question': 'Compare the top vector databases',
'mode': 'standard'
},
)
data = res.json()Go
body := `{
"question": "Compare the top vector databases",
"mode": "standard"
}`
req, _ := http.NewRequest("POST", "https://api.infrence.ai/v1/research", strings.NewReader(body))
req.Header.Set("Authorization", "Bearer inf_live_…")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)Rust
let body = serde_json::json!({
"question": "Compare the top vector databases",
"mode": "standard"
});
let res = reqwest::Client::new()
.post("https://api.infrence.ai/v1/research")
.bearer_auth("inf_live_…")
.json(&body)
.send()
.await?;