Research jobs
Submit, list, inspect, and cancel research jobs. 10 credits per uncached domain for a full read; quick reads cost 1 credit per name when the routing pass returns one.
List research jobs
List the authenticated organization's research jobs, newest first. Paginated.
query Parameters
limitPage size. Defaults to 20. Minimum 1, maximum 100 - values above 100 are clamped to 100.
cursorOpaque pagination cursor returned in the previous response.
List research jobs › Responses
Page of research jobs.
next_cursorSubmit a research job
Submit between 1 and 100 domains for a full read on every name. 10 credits per uncached domain. Cached domains return their existing report immediately at no cost. The Idempotency-Key header is required - reusing a key within 24 hours returns the original job.
Headers
Idempotency-KeyClient-generated UUID. Identical keys within 24 hours return the original job; different keys are independent submissions.
Submit a research job › Request Body
domainsBetween 1 and 100 unique domains.
labelOptional human-readable label shown in the dashboard, completion email, and activity feed.
Submit a research job › Responses
Job accepted and started. The response carries the job's per-domain breakdown; uncached names are still 'pending' or 'running'. Poll GET /v1/research-jobs/{id} every few seconds until counts.pending and counts.running reach 0.
idstatusmode'full' (POST /v1/research-jobs) runs the full multi-model appraisal on every domain at 10 credits each. 'quick' (POST /v1/research-jobs/quick) routes each name through a fast first-pass that decides whether the full appraisal is worth it: names judged worthy run the full appraisal (10 credits each); the rest get a quick-read pricing estimate (1 credit each). Credits are reserved at the worst case (10 per name) and the running total settles down as quick reads come back.
submitted_atdomains_totallabelcompleted_atdomains_completeddomains_failedcredits_chargedSum of per-domain charges so far. For quick-mode jobs this number settles down as each name's decision lands - quick reads keep 1 credit, full reads keep 10.
credits_refundedPer-domain status for this job.
Submit a quick-read research job
Submit 1-100 domains for quick reads. Each name goes through a fast routing pass that decides whether the full appraisal is worth it:
- Quick read (
read_type="quick") - the routing pass judged the name not worth the full appraisal. You get a first-pass wholesale / aftermarket / brokered estimate plus a one-sentence rationale. 1 credit per name. - Full read (
read_type="full") - the routing pass judged the name worth the deep appraisal, which runs end to end (every signal, every probe, every recommendation). 10 credits per name.
The job returns 202 immediately; the per-name decisions land asynchronously. Poll GET /v1/research-jobs/{id} until counts.pending and counts.running reach 0.
Credits are reserved at the worst case (10 per uncached name) and the running total settles down as quick reads come back. credits_charged on the job payload is the authoritative running total - always reflects what your wallet actually paid.
Idempotency-Key works the same as the full endpoint.
The POST /v1/research-jobs endpoint (without /quick) is unchanged - every domain runs the full appraisal at 10 credits each, no routing involved.
Headers
Idempotency-KeyClient-generated UUID. Identical keys within 24 hours return the original job; different keys are independent submissions.
Submit a quick-read research job › Request Body
domainsBetween 1 and 100 unique domains.
labelOptional human-readable label shown in the dashboard, completion email, and activity feed.
Submit a quick-read research job › Responses
Job accepted and started. mode="quick" on the response. Per-domain credits_charged settles as each name's routing decision lands (1 credit for a quick read, 10 credits for a full read).
idstatusmode'full' (POST /v1/research-jobs) runs the full multi-model appraisal on every domain at 10 credits each. 'quick' (POST /v1/research-jobs/quick) routes each name through a fast first-pass that decides whether the full appraisal is worth it: names judged worthy run the full appraisal (10 credits each); the rest get a quick-read pricing estimate (1 credit each). Credits are reserved at the worst case (10 per name) and the running total settles down as quick reads come back.
submitted_atdomains_totallabelcompleted_atdomains_completeddomains_failedcredits_chargedSum of per-domain charges so far. For quick-mode jobs this number settles down as each name's decision lands - quick reads keep 1 credit, full reads keep 10.
credits_refundedPer-domain status for this job.
Rerun a single domain
Force a fresh appraisal on one domain. Default body is empty (full read, 10 credits). Pass {"quick": true} to use the same routing pass the quick endpoint uses (1 credit if the routing pass returns a quick read, 10 credits if it judges the name worth the full appraisal).
Unlike the cached read of GET /v1/domains/{domain}/pricing, this endpoint always runs a fresh appraisal - useful when you want to refresh a stale result or upgrade a quick read to the full appraisal. The new result overwrites the prior one for future reads of /v1/domains/{domain}/pricing and the report endpoints (a full read always overrides a quick read for the same name; the earlier entry stays in your history).
This is the API equivalent of the dashboard's "Run full read" upgrade button. Customers who got a quick read in a bulk job can upgrade individual names without resubmitting the whole job.
path Parameters
domainThe domain name (e.g. acme.ai).
Headers
Idempotency-KeyRerun a single domain › Request Body optional
quickWhen true, use the routing pass (may return a quick read for 1 credit, or run the full appraisal for 10 credits). Default false always runs the full appraisal at 10 credits.
Rerun a single domain › Responses
Rerun started or completed.
run_iddomainstatusmodecredits_charged1 for a quick read; 10 for a full read (reserved up front; finalized when the appraisal finishes).
credits_balance_afterread_typePopulated immediately for a quick read (the rerun returns terminal in-line). Null for a full read while the appraisal is still running; poll GET /v1/domains/{domain}/pricing for the eventual result.
read_reasonThe routing model's one-sentence rationale for the read tier this name received. Present on quick reads and on full reads that came from the quick endpoint; null for full reads submitted directly to /v1/research-jobs.
Get research job status
path Parameters
idGet research job status › Responses
Job state and per-domain status.
idstatusmode'full' (POST /v1/research-jobs) runs the full multi-model appraisal on every domain at 10 credits each. 'quick' (POST /v1/research-jobs/quick) routes each name through a fast first-pass that decides whether the full appraisal is worth it: names judged worthy run the full appraisal (10 credits each); the rest get a quick-read pricing estimate (1 credit each). Credits are reserved at the worst case (10 per name) and the running total settles down as quick reads come back.
submitted_atdomains_totallabelcompleted_atdomains_completeddomains_failedcredits_chargedSum of per-domain charges so far. For quick-mode jobs this number settles down as each name's decision lands - quick reads keep 1 credit, full reads keep 10.
credits_refundedPer-domain status for this job.
Cancel a research job
Stops a running job. Returns whatever credits were still reserved for names that hadn't finished yet - names that already came back keep their charge (10 credits for a full read, 1 for a quick read). The response carries credits_refunded so you can see exactly how much landed back in your wallet. Idempotent: calling it on an already-terminal job returns 409.
path Parameters
idCancel a research job › Responses
Job cancelled. Returns the final state.
idstatusmode'full' (POST /v1/research-jobs) runs the full multi-model appraisal on every domain at 10 credits each. 'quick' (POST /v1/research-jobs/quick) routes each name through a fast first-pass that decides whether the full appraisal is worth it: names judged worthy run the full appraisal (10 credits each); the rest get a quick-read pricing estimate (1 credit each). Credits are reserved at the worst case (10 per name) and the running total settles down as quick reads come back.
submitted_atdomains_totallabelcompleted_atdomains_completeddomains_failedcredits_chargedSum of per-domain charges so far. For quick-mode jobs this number settles down as each name's decision lands - quick reads keep 1 credit, full reads keep 10.
credits_refundedPer-domain status for this job.
Get all domain reports for a job
Returns every domain in the job with its current job_status and (when computed) its full DomainReport. Customers poll this during a running job to watch reports fill in; once terminal, it's a one-shot answer for 'give me everything from this submission.'
Domains in pending or running status carry only domain + job_status — no report key (the omit-when-null contract). paid and cached domains carry the full DomainReport. failed domains carry an error code (see "Error codes" in the docs).
path Parameters
idGet all domain reports for a job › Responses
Job header + array of per-domain reports.
Get pricing-only slice for every domain in a job
Pricing-only variant of /v1/research-jobs/{id}/report. Each entry carries the price band (wholesale / aftermarket / brokered), reasoning, key factors, and risks - capped at 4 KB per text field. Faster and lighter than the full report wrapper; built for the 'CSV of just the dollars and reasoning' workflow without pulling the probes / signals / brand signals you don't need.
Pass ?format=csv to receive a browser-downloadable CSV instead of JSON. The CSV contains one row per domain in the job, with the same data as the JSON response projected into a flat row format. Failed entries occupy a row with the error column populated and the dollar columns blank.
path Parameters
idquery Parameters
formatResponse format. Defaults to JSON. Pass ?format=csv to receive a browser-downloadable CSV (one row per domain) with columns: domain, job_status, confidence, wholesale_low/mid/high, aftermarket_low/mid/high, brokered_low/mid/high, model, engine_version, computed_at, error, reasoning, key_factors, risks. The CSV is BOM-prefixed for Excel UTF-8 compatibility, uses CRLF line terminators per RFC 4180, and serves with Content-Disposition: attachment.
Get pricing-only slice for every domain in a job › Responses
Job header + array of per-domain pricing slices.