Partner integration
Building ora scores into your own product takes two endpoints: one runs a scan, one reads the latest stored result. Call both from your server with a scan API key, and render the response as ora returns it.
1. Run a scan. Stream it, and forward the events to your UI. Add force=1 to rescan a result younger than the 6-hour freshness window.
scan_complete carries the audit in result and the site-type reading beside it in siteType. A live scan may then send relevance_assessed (checks marked not applicable, plus the corrected score and grade) and summary_ready; both are optional. Read events until the stream closes, then go to step 2. A closed stream is not always a final score: when deep checks are still running, ora finishes the analysis in the background. If you cannot hold a stream open, POST /api/scan returns the same audit in one response, and a 202 points you at the score endpoint to poll.
2. Read the stored score. This never starts a scan. While analysisStatus is partial, the score can still change: poll until it reads complete. Add &siteType=store (or content, business, app) to read the scan as that type. The siteType reading is experimental: its shape can change without a contract version bump.
It reads by hostname, so a path such as example.com/mcp returns the scan for example.com. A 404 means the site has not been scanned yet: run step 1.
score, grade, every check in layers[].checks[], and topFixes in the order ora sends them. Do not recompute scores, drop checks, or rewrite statuses. Accept contractVersion major 1 and ignore fields you do not recognize: minor releases add them. The versioning policy lists which fields are stable.Agent journeys
A journey sends a real agent at the site and records every step it takes. Your key unlocks one call that returns a domain's journey, starting one only when none exists.
1. Get the domain's journey. Send no body: ora picks the task and the agent. A 201 means a new run started. A 200 means nothing new ran: you get the stored run, with its result and run_age_seconds once status is succeeded. A succeeded journey is kept indefinitely and serving it costs nothing, so call this on every page view. A failed run carries no result and is not kept: the next call starts a new run, so back off after a failure instead of retrying at once.
The response is a compact view with what drawing the journey needs: verdict, the steps in result.trajectory.steps, and result.insight.summary. Add ?view=full for the full payload, including key_observations.
2. Stream a running journey to the end. While status is running, open stream_url (a path on ora.ai) and read it until result or error. Hold it open: the stream is what saves the finished run, so calling step 1 again only reads what a stream has saved. If the connection drops, open it again; it picks up the same run without restarting the agent. A run can take up to 10 minutes. Open it from your server with your key: it has no CORS headers, and the key lifts the per-IP limit your viewers would otherwise share.
The stream sends run_id, then trajectory snapshots (each one carries every step so far), then result. A live run also sends processing while insights are written; reopening a finished run does not. error can arrive at any point and ends the stream. A running 200 from step 1 carries retry_after_ms; more than three calls for one domain within two seconds return 429 POLL_TOO_FAST. Every 429 carries a Retry-After header.
Your own tasks. To run a task you write, send it as free text (4 to 300 characters) with an agent from GET /api/journey/agents. This starts a new run on every call, up to 1,000 per key per 24 hours. Stream the stream_url it returns to the end, as in step 2. Afterwards, GET /api/journey/runs/{id} reads the saved run.
verdict ora assigns (satisfied, partial, unsatisfied, or not_gradable). A journey records what an agent did. It has no score and does not map to the scan's layers. The request and response schemas are in the OpenAPI spec under /api/journey.