Start or resume a durable investigation
Research Harness API
The public API accepts Research work asynchronously. Each API-key mutation returns an accepted thread/run identity, while durable execution and product reads continue outside the initial HTTP request.
Authentication
API key
Send x-api-key or a Bearer API key with research:write permission.
Mutation safety
Idempotent
Every POST requires an Idempotency-Key so a retry returns the original work.
Response
202 Accepted
The route acknowledges durable admission; it does not wait for research to finish.
Section 1
Implemented route inventory
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/research/run | Create a new persistent thread and its first asynchronous run. |
| POST | /api/v1/research/threads/{encrypted_id}/run | Add a focused prompt to an owned thread. |
| POST | /api/v1/research/runs/{run_id}/continue | Resume a partial, failed, or credit-exhausted run. |
| GET | /api/v1/research/runs/{run_id} | Poll one owned run's durable status. Requires research:read. |
| GET | /api/v1/research/portfolio | Page the caller's research threads. Requires research:read. |
| GET | /api/v1/research/threads/{encrypted_id} | Read one owned thread and its rollup counters. Requires research:read. |
| POST | /api/research/threads/{encrypted_id}/artifacts/{artifact_encrypted_id}/deep | Start a bounded artifact deep dive through a browser session. |
Section 2
Create a thread or add a prompt
Use POST /api/v1/research/run to create a new persistent thread with its first run. Use POST /api/v1/research/threads/{encrypted_id}/run when a new question should join an existing owned collection. Both routes accept the same JSON request fields and require Idempotency-Key, except that reference_artifact_ids works only when appending; create refuses any value with 422.
Send either x-api-key: vb_live_... or Authorization: Bearer vb_live_..., plus a JSON content type. The API key must carry research:write, and the GET read routes require research:read.
| Field | Type | Required | Current contract |
|---|---|---|---|
| prompt | string | Required | The question that gives the investigation its direction and helps each source artifact stay relevant. Keep it between 1 and 20,000 characters so the request remains useful without becoming an unbounded brief. |
| size | small | medium | large | Optional | Chooses a preset level of source coverage and discovery effort for the run. Use it when a simple capacity choice is more helpful than setting each target separately; the available presets map to 15, 50, or 100 sources. |
| target_sources | integer | Optional | Sets the number of sources the investigation should try to examine. The value can be from 1 through 1,000, which keeps the requested scope explicit and bounded before work starts. |
| search_calls | integer | Optional | Sets how many discovery searches the run must make while looking for useful material, from 1 through 100. When searches come back empty the run may make up to 4 more, never more than 100 in all, and its wallet hold covers that maximum. |
| resource_kinds | paper[] | web[] | Optional | Chooses whether the investigation looks across scholarly papers, general web resources, or both. At least one and no more than two implemented resource kinds may be supplied, and the default includes both. |
| source_sites | string[] | Optional | Suggests reviewed source sites that should influence where discovery looks for material. These are soft preferences, so unknown site values may be ignored instead of preventing the rest of the investigation from running. |
| include_domains / exclude_domains | string[] | Optional | include_domains narrows discovery to hosts from a reviewed list of 39 scholarly sites, such as arxiv.org, pubmed.ncbi.nlm.nih.gov, and nature.com; any other host returns 422. exclude_domains keeps any hostname out of the search. Each list takes up to 50 hostname-only entries, and the two lists must not contain the same domain. |
| published_after / language | string | Optional | Filters discovery toward material published after a calendar date and written in a preferred language. The date must be calendar-valid ISO format, while language values are limited to the supported two-to-twelve character range. |
| reference_artifact_ids | string[] | Optional | Adds a small set of already-saved artifacts as deliberate context for the next investigation, when appending to a thread. Supply up to 15 unique encrypted public tokens and use request schema version 2; previous artifact bodies are not loaded automatically. Create refuses any value with 422, because a new thread has no saved artifacts. |
Create a Research thread
curl -X POST "https://vidbyte-backend.onrender.com/api/v1/research/run" \
-H "x-api-key: $VIDBYTE_API_KEY" \
-H "Idempotency-Key: research-competitor-landscape-001" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Map the evidence and competitive landscape for AI tutoring",
"size": "small",
"resource_kinds": ["paper", "web"],
"language": "en"
}'Section 3
Handle the accepted response
A successful mutation returns 202 Accepted after it has durably admitted the work and emitted the execution event. Store both identifiers: encrypted_id names the long-lived collection and run_id names this one execution envelope. encrypted_id is the only thread identifier the API accepts; run status and thread reads also return an internal thread_id, which no route accepts.
202 Accepted
{
"encrypted_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"run_id": "rrun_...",
"status": "accepted"
}Section 4
Continue or curate research
Use POST /api/v1/research/runs/{run_id}/continue with the same API-key and idempotency headers after a partial, failed, or credit-exhausted run can proceed. It preserves the run identity and uses durable membership to avoid recomputing ready artifacts.
Artifact deletion is intentionally separate: DELETE /api/research/threads/{encrypted_id}/artifacts/{artifact_encrypted_id} is a browser-session route for the verified owner, not an API-key route.
Reference map
Every implemented route
POST
Create run
POST
Append run
POST
Continue run
GET
Get run
GET
Portfolio
GET
Get thread
Browser session