[ Trusted by builders from ]NetflixServiceNowCiscoAdobePayPalAmazonDatadogJPMorgan ChaseDell
[ Trusted by builders from ]NetflixServiceNowCiscoAdobePayPalAmazonDatadogJPMorgan ChaseDell
Prior.Runprior.run

FIG · 01— rest endpoint specification, v1

Ship after simulation.

The same engine you drive through the web UI, exposed as JSON over HTTPS. Build CI gates. Ship agents. Stop checking screenshots.

~/prior.run — curllive
$ curl https://api.prior.run/api/v1/ads/compare
  -H "Authorization: Bearer $PR_KEY"
  -d '{"image_a": "…", "image_b": "…", …}'

// running ···························

 {
    "memo_id": "comp_b81b0b93",
    "status": "complete",
    "memo": { verdict: { winner: "A" }, confidence_level: "Moderate", verdict_headline: "We prefer Design A" … }
}

Production hostprod
https://api.prior.run
Local dev hostdev
http://localhost:8000
Bearer tokenrequired
Authorization: Bearer pr_live_••••••••••••

Generate at /settings. Plaintext shown once.


Every product memo the web UI produces — verdict, reactions, quotes, audience preference, risk flags — in one JSON response.

POST/api/v1/design/reviewsingle design01
POST/api/v1/design/comparetwo variants02

Scroll-stop, hook clarity, brand recall. Platform-aware when you pass run_platform=meta | tiktok | google. Inspiration drafts bundle action items into one new image + body copy + headline + CTA — CTA is auto-snapped to the platform's allowed list. Creative-from-fieldnotes turns a focus-group room's consensus / tension / surprise notes into three archetype variants (quote · editorial · bold_graphic) — no memo required; the hook always lifts a verbatim phrase from the transcript.

POST/api/v1/ads/singleone creative01
POST/api/v1/ads/comparetwo head-to-head02
POST/api/v1/ads/inspirationdraft from recs · single + compare03
GET/api/v1/ads/inspiration/{id}latest draft04
POST/api/v1/ads/creative-from-fieldnotes3 variants from a focus-group's field notes05
POST/api/v1/ads/creative-flattencomposite overlay onto a bare image06

Synthetic personas walk a real website and produce the same memo shape as image audits. Pass mode=explore for free roam, flow for a guided funnel, or quiz for a verdict-pressure walk. Credits-charged per run. Long-running — the endpoint blocks until synthesis is complete (~5–10 min).

POST/api/v1/url/auditwalk one live URL · mode = explore | flow | quiz01
POST/api/v1/url/comparetwo URLs head-to-head · same mode enum02
GET/api/v1/url/audit/costcredit cost preview03
GET/api/v1/url/compare/costcredit cost preview04

Mine the open web for what real people say about a brand. Asynchronous — POST returns a job_id immediately, poll until status='completed' (~15–25 min), then GET the corpus.

POST/api/v1/moodkick off pipeline (returns job_id)01
GET/api/v1/mood/jobs/{id}poll job status02
GET/api/v1/moodlist caller's reports03
GET/api/v1/mood/{id}full corpus JSON04
GET/api/v1/mood/{id}/cohortslist cohort_ids for spawn05
POST/api/v1/mood/{id}/regeneratefresh mine, same URL06
POST/api/v1/mood/{id}/spawn-audiencespanel → synthetic audiences07

Create returns a memo_id immediately. Poll until status = complete — typically 75–120s for ads, 90–180s for non-ads. GET /memo/{id} accepts either the internal memo UUID or the share_token returned at creation — both resolve to the same memo.

GET/api/v1/memo/{id}full memo JSON · accepts memo UUID or share_token01
GET/api/v1/ads/inspiration/{id}latest ads inspiration draft02
GET/api/v1/audience-templateslist built-in audience templates03
GET/api/v1/audienceslist caller's saved custom audiences (id + name)04
PATCH/api/v1/audiences/{id}rename a saved custom audience05
DELETE/api/v1/audiences/{id}delete a saved custom audience06

Follow-up Q&A with synthetic personas — either one persona on a memo, or the whole focus-group room for a saved custom audience. Capped per (memo, persona, viewer) and per audience to keep the panel honest.

POST/api/v1/persona/interviewask one persona on a memo (capped per viewer)01
GET/api/v1/persona/interview/historytranscript + remaining budget02
GET/api/v1/persona/audience-panelopen focus-group room for a saved audience03
POST/api/v1/persona/audience-askask the whole room one question (fans out)04
POST/api/v1/persona/audience-synthesistranscript → themes + quotes + dissent05

01 · kickoff↳ returns memo_id immediately
01curl -X POST https://api.prior.run/api/v1/ads/compare \
02 -H "Authorization: Bearer $PRIORRUN_API_KEY" \
03 -H "Content-Type: application/json" \
04 -d '{
05 "image_a": "https://cdn.brand.com/hero-a.png",
06 "image_b": "https://cdn.brand.com/hero-b.png",
07 "campaign_context": "Gen Z skincare, TikTok awareness.",
08 "run_platform": "tiktok"
09 }'
02 · response↳ memo_id, url, status=pending
01{
02 "memo_id": "comp_b81b0b93",
03 "status": "pending",
04 "url": "https://prior.run/ads/memo/comp_b81b0b93"
05}
03 · poll until complete↳ ~90s end-to-end
01curl https://api.prior.run/api/v1/memo/comp_b81b0b93 \
02 -H "Authorization: Bearer $PRIORRUN_API_KEY"
03
04# → { memo_id, status: "complete", memo: { verdict,
05# quotes, action_items, lens_highlights, ... } }

rule i

Images


Base64, data URL, or https. Max 10 MB.

rule ii

Dedup


Duplicate or near-duplicate images rejected (400).

rule iii

Text limits


campaign_context + hypothesis: 500. custom_audience: 2500. creative_name: 60. metric: 120. Sanitized for injection.

rule iii·b

Audiences


Every memo endpoint (design/ads/url) accepts audience_template (built-in key) or custom_audience_id (saved audience UUID). custom_audience_id wins when both are set.

rule iv

Live URLs


https only, max 2048 chars. url_a ≠ url_b for compare.

rule v

Mood


Async pipeline. POST returns job_id · poll /mood/jobs/{id} until status=completed.

rule vi

Auth


Bearer pr_live_… . Keys are user-scoped.

rule vii

Polling


Create returns memo_id · poll GET /memo/{id} until status=complete.


Error codes↳ HTTP status · meaning
400Invalid input — bad JSON, missing fields, duplicate images, oversized text.
401Missing or invalid bearer token. Generate a new key at /settings.
403Quota exhausted or plan does not include this endpoint.
404memo_id, job_id, or template not found for this account.
413Payload too large — image over 10 MB or URL over 2048 chars.
429Rate limit exceeded. Respect the Retry-After header before retrying.
500Server error. Safe to retry the same request once.
504Synthesis took too long. Re-poll GET /memo/{id} — do not re-submit.
rule i

Rate limits


Per-key request rate and concurrent-job caps apply. Bursts → 429 with Retry-After. Upgrade plan to raise the ceiling.

rule ii

Polling cadence


Poll GET /memo/{id} every ~5s. Stop at status=complete or status=failed. Don't re-submit on 504 — just re-poll.

rule iii

Key lifecycle


Keys are user-scoped, shown in plaintext once at creation. Rotate or revoke any time at /settings. Old keys 401 instantly.

↳ Duplicate image submissions inside the same compare body are rejected with 400 — treat this as built-in idempotency for re-submits within a short window.


[ end of specification ]

Or skip the curl.
Use an agent.