REST API
Discovery + validation liveRequest feasibility, pricing and research programmatically.
A versioned JSON API for platforms that need to commission new primary research. Capability discovery and stateless brief validation are public through REST and equivalent read-only MCP tools. Estimates, firm quotes, orders, payments and delivery require verified organisational access, purchasing authority and agreed commercial terms.
POST /api/v1/estimates
Authorization: Bearer <partner_token>
Idempotency-Key: 5f1c…
{
"brief": {
"purpose": "Understand prescribing barriers for a new anticoagulant",
"markets": ["ES"],
"audience": {
"type": "physician",
"specialty": "cardiology",
"screening": ["treats >= 20 AF patients / month"]
},
"method": "cawi",
"n": 200,
"loi_minutes": 15,
"incidence": { "assumption": 0.35, "source": "buyer" },
"deliverables": ["csv", "codebook", "metadata"],
"priority": "standard"
}
}Endpoints
Public surface and managed commercial access
Public rows are callable without onboarding. Managed rows require organisation-specific credentials and permissions; calls to those paths on the unauthenticated public surface return HTTP 501 and create no obligation.
| Method | Path | Tool | Class | Status |
|---|---|---|---|---|
| GET | /api/v1/capabilities | search_research_capabilities | read | public |
| POST | /api/v1/briefs/validate | validate_research_brief | read | public |
| POST | /api/v1/estimates | estimate_project | read | managed setup |
| POST | /api/v1/quotes | request_binding_quote | controlled | managed setup |
| GET | /api/v1/quotes/{quote_id} | get_quote | read | managed setup |
| POST | /api/v1/orders | prepare_order | controlled | managed setup |
| POST | /api/v1/orders/{order_id}/approval | request_approval | controlled | managed setup |
| POST | /api/v1/orders/{order_id}/contract | create_contract | commit | managed setup |
| POST | /api/v1/orders/{order_id}/payment | create_payment | commit | managed setup |
| POST | /api/v1/orders/{order_id}/start | start_project | commit | managed setup |
| GET | /api/v1/projects/{project_id} | get_project_status | read | managed setup |
| GET | /api/v1/projects/{project_id}/deliverables | list_deliverables | read | managed setup |
| POST | /api/v1/projects/{project_id}/changes | request_change_or_cancel | commit | managed setup |
The public OpenAPI document is the canonical contract for unauthenticated operations. Commercial paths without an approved organisation context return 501 organisation_setup_required with machine-readable onboarding links.
MCP clients can call the equivalent public read-only tools at https://researchpricer.vercel.app/api/mcp. Commercial MCP tools are not exposed there.
Example
An estimate never pretends to be a price.
The engine returns ranges, timing, confidence and the fields it still needs. Prices in examples are deliberately null: real values come from the pricing engine, never from documentation.
POST /api/v1/estimates
Authorization: Bearer <partner_token>
Idempotency-Key: 5f1c…
{
"brief": {
"purpose": "Understand prescribing barriers for a new anticoagulant",
"markets": ["ES"],
"audience": {
"type": "physician",
"specialty": "cardiology",
"screening": ["treats >= 20 AF patients / month"]
},
"method": "cawi",
"n": 200,
"loi_minutes": 15,
"incidence": { "assumption": 0.35, "source": "buyer" },
"deliverables": ["csv", "codebook", "metadata"],
"priority": "standard"
}
}HTTP/1.1 200 OK
Content-Type: application/json
{
"estimate_id": "est_01J…",
"brief_hash": "sha256:9c4e…",
"state": "indicative_only",
"lane": "amber",
"price_range": { "currency": "EUR", "min": null, "max": null,
"note": "returned by the pricing engine" },
"timing_range_days": { "min": 8, "max": 12 },
"confidence": 0.7,
"missing_fields": ["language", "incentive_policy", "consent_text"],
"assumptions": ["incidence 35% (buyer-stated)", "questionnaire supplied by buyer"],
"next": {
"action": "request_binding_quote",
"expected_by": "2 business hours after missing fields are supplied"
}
}Quote payload
The minimum quote object
Everything an agent — or a procurement system — needs to decide, approve and audit.
| Field | Type | Note |
|---|---|---|
| quote_id, version | string, int | Immutable; any change produces a new version |
| quote_type | estimate | conditional | firm | Only firm quotes are executable |
| currency, net, tax, gross | ISO 4217, minor units | Tax computed per buyer entity |
| markets[] | ISO 3166-1 | Per-market sample and language |
| target | object | Audience definition, screening criteria, exclusions |
| method | enum | cawi, cati, capi, idi, focus_group, community, ethnography, mystery_shopping, clt, recruitment… |
| n, loi_minutes / duration_minutes | int | Sample or interview count; length |
| incidence_assumption, incidence_source | number, string | Stated, never inferred silently |
| inclusions[], exclusions[] | string[] | Exactly what the price covers |
| earliest_start, delivery_window | date, {min,max} days | From approval and funds |
| confidence, evidence_classes[], evidence_dates[] | 0–1, string[], date[] | Why the price is what it is |
| valid_until | datetime | Typically 48h for firm quotes |
| approval_level | human | mandate | Determined by amount, audience and market |
| payment_schedule[] | milestone[] | Deposit, interim, on acceptance |
| cancellation_ladder[] | stage → cost | Non-recoverable costs by stage |
| data_roles, change_order_rules | object | Controller/processor, retention, transfers |
Authentication
OAuth 2.0 client credentials per partner organisation; optional signed agent identity headers. Tokens are scoped to read, controlled or commit classes.
Idempotency & audit
Every mutation requires an Idempotency-Key. Responses include correlation IDs; quotes and orders are hash-linked to the brief they came from.
Errors
Deterministic error codes (needs_clarification, unsupported_audience, restricted_population, mandate_exceeded, quote_expired) with human-readable remediation.
Configure the commercial contract for your agents.
Integration partners define the permitted tools, organisation identity, approval thresholds, payment terms and sandbox path with the ResearchPricer team.