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 shape and require `Idempotency-Key`.
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 calls the run may make while looking for useful material. The value can be from 1 through 100, giving the investigation a visible search effort limit. |
| 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 | Narrows discovery to approved hostnames or keeps selected hostnames out of the search. Values must be 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. Supply up to 15 unique encrypted public tokens and use request schema version 2; previous artifact bodies are not loaded automatically. |
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 or returns.
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