Developer API

Consent Checker API

Run consent checks programmatically, track status, fetch reports, delete persisted runs, start background assessment generation, and poll for summaries without waiting on long responses.

Get API Key
Good to know: Runs started through the API still appear in the web app. Returned links include the live browser session, report, raw session JSON, analysis endpoint, screenshots endpoint, delete endpoint, and the Results page in the GUI.
1. Get a key

Open Account, create an API key, and copy it once.

2. Start a run

Call POST /api/v1/runs with a URL, task, and optional state.

3. Manage runs

Use the returned links for status, report, session JSON, screenshots, async analysis, and delete completed runs with DELETE /api/v1/runs/<session_id> when you no longer need them.

Consent Checker API

Build against the same consent-testing engine that powers the web app and MCP server.

The API is intentionally simple:

  • one API key belongs to one subscribed account
  • every run created with that key belongs to that account
  • API-created runs still appear in the web app GUI
  • the live browser session still opens in the web app
  • completed reports still show up in My Tests and the Results page

What You Get

  • Start a consent check run
  • Poll run status
  • List your recent runs
  • Fetch the markdown report
  • Fetch the raw run session JSON
  • Fetch screenshot metadata and browser-usable image URLs
  • Fetch the detailed tracking markdown artifact used by AI summaries
  • Start background generation for the same assessment-style analysis shown in the Results page
  • Start background generation for got cipa? analysis on California runs
  • Poll the current analysis status and fetch the generated summary when ready

Base URL:

https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1

Authentication header:

Authorization: Bearer <api_key>

1. How To Get An API Key

  1. Log in to the web app.
  2. Make sure your account has an active subscription.
  3. Open Account.
  4. In the API Access section, click Create API Key.
  5. Copy the key immediately.

Important:

  • the plaintext key is shown only once
  • existing keys can be listed by prefix and revoked later
  • if you revoke a key, any integration using it stops working immediately

2. Quickstart

Set your key:

export CONSENT_API_KEY='your_api_key_here'

Create a run:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "task": "reject_all",
    "state": "US-CA",
    "wait_for_debug_url_seconds": 3
  }'

Example success response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "task_id": "4ab5e1df-3b12-4d17-a8b4-98b8d4f8a0f6",
  "status": "started",
  "message": "Analysis started successfully",
  "debug_url": "https://www.browserbase.com/sessions/...",
  "links": {
    "status": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "report": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/report",
    "session": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/session",
    "analysis": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/analysis",
    "live_view": "/live/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "results": "/results/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68"
  }
}

What good looks like:

  • you get back a session_id
  • status is started
  • links.live_view opens the same live session in the web app
  • once complete, the run appears in the GUI under My Tests

3. Endpoint Reference

Quick scan:

Method Path What it does
GET /api/v1 Returns a lightweight API index.
POST /api/v1/runs Starts a new consent check run.
GET /api/v1/runs Lists recent persisted runs for the API key owner.
GET /api/v1/runs/<session_id> Returns the latest status for one run.
DELETE /api/v1/runs/<session_id> Deletes a persisted run and its stored artifacts.
GET /api/v1/runs/<session_id>/report Returns the completed markdown report.
GET /api/v1/runs/<session_id>/session Returns the raw session JSON for a completed run.
GET /api/v1/runs/<session_id>/screenshots Returns screenshot metadata and browser-usable URLs.
GET /api/v1/runs/<session_id>/tracking-data Returns the detailed tracking markdown artifact used by summaries.
GET /api/v1/runs/<session_id>/analysis Returns the current default analysis state and summary, if available.
POST /api/v1/runs/<session_id>/analysis Starts default analysis generation in the background.
GET /api/v1/runs/<session_id>/cipa-analysis Returns the current got cipa? analysis state for California runs.
POST /api/v1/runs/<session_id>/cipa-analysis Starts got cipa? analysis generation in the background for California runs.

Shared conventions:

  • analysis-style endpoints may return a JSON body with status values such as not_ready, not_generated, pending, running, completed, failed, or report_not_available
  • POST analysis endpoints return 202 Accepted when work is queued or in progress, and 200 OK when a cached or completed summary is returned immediately
  • GET /cipa-analysis and POST /cipa-analysis return 400 Bad Request for non-California runs
  • summary endpoints return HTML in summary
  • summary retrieval is language-aware: if the request is made with the app's French language context, the API may return a French translated summary; otherwise English is the default

GET /api/v1

What it does:

  • returns a lightweight API index
  • useful for checking that the API is reachable

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1 \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "name": "Consent Checker API",
  "version": "v1",
  "auth": "Bearer API key",
  "endpoints": {
                        "create_run": "/api/v1/runs",
                        "get_run_status": "/api/v1/runs/<session_id>",
                        "delete_run": "/api/v1/runs/<session_id>",
                        "list_runs": "/api/v1/runs",
                        "get_run_report": "/api/v1/runs/<session_id>/report",
                        "get_run_session": "/api/v1/runs/<session_id>/session",
                        "get_run_screenshots": "/api/v1/runs/<session_id>/screenshots",
                        "get_run_tracking_data": "/api/v1/runs/<session_id>/tracking-data",
                        "analyze_run": "/api/v1/runs/<session_id>/analysis",
                        "analyze_run_cipa": "/api/v1/runs/<session_id>/cipa-analysis"
  }
}

POST /api/v1/runs

What it does:

  • starts a new consent check run for the account that owns the API key

Input format:

{
  "url": "https://example.com",
  "task": "reject_all",
  "state": "US-CA",
  "wait_for_debug_url_seconds": 3
}

Field notes:

  • url: required, target website
  • task: optional, defaults to reject_all
  • task supports accept_all, reject_all, gpc, granular_preferences
  • state: optional, defaults to US-CA
  • granular_preference_prompt: advanced optional field, required only when task is granular_preferences
  • wait_for_debug_url_seconds: optional, lets the API wait briefly for the live debug URL

No new create-run parameter is required for got cipa? analysis. Create the run with state set to US-CA or CA, then call the separate /cipa-analysis endpoint after the run completes. Existing POST /api/v1/runs workflows continue to work unchanged.

This API behavior is separate from the web UI's mode persistence. The web UI can still remember and pass its selected mode across pages; the public create-run API simply does not require a new field for existing integrations.

Output format:

{
  "session_id": "uuid",
  "task_id": "worker-task-id",
  "status": "started",
  "message": "Analysis started successfully",
  "debug_url": "https://...",
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "report": "/api/v1/runs/<session_id>/report",
    "session": "/api/v1/runs/<session_id>/session",
    "screenshots": "/api/v1/runs/<session_id>/screenshots",
    "analysis": "/api/v1/runs/<session_id>/analysis",
    "cipa_analysis": "/api/v1/runs/<session_id>/cipa-analysis",
    "tracking_data": "/api/v1/runs/<session_id>/tracking-data",
    "live_view": "/live/<session_id>",
    "results": "/results/<session_id>"
  }
}

Good example:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://www.nytimes.com",
    "task": "gpc",
    "state": "US-CA"
  }'

GET /api/v1/runs/<session_id>

What it does:

  • returns the latest status for one run
  • only works if the run belongs to the API key owner

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id> \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response while running:

{
  "url": "https://example.com",
  "task": "reject_all",
  "status": "running",
  "progress": 35,
  "message": "Processing...",
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "report": "/api/v1/runs/<session_id>/report",
    "session": "/api/v1/runs/<session_id>/session",
    "screenshots": "/api/v1/runs/<session_id>/screenshots",
    "analysis": "/api/v1/runs/<session_id>/analysis",
    "cipa_analysis": "/api/v1/runs/<session_id>/cipa-analysis",
    "tracking_data": "/api/v1/runs/<session_id>/tracking-data",
    "live_view": "/live/<session_id>",
    "results": "/results/<session_id>"
  }
}

Example response when complete:

{
  "url": "https://example.com",
  "task": "reject_all",
  "status": "completed",
  "progress": 100,
  "debug_url": "https://www.browserbase.com/sessions/...",
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "report": "/api/v1/runs/<session_id>/report",
    "session": "/api/v1/runs/<session_id>/session",
    "screenshots": "/api/v1/runs/<session_id>/screenshots",
    "live_view": "/live/<session_id>"
  }
}

What good looks like:

  • status eventually becomes completed
  • you can open links.live_view in the web app
  • the run later appears in the GUI under My Tests

DELETE /api/v1/runs/<session_id>

What it does:

  • permanently deletes a persisted run owned by the API key account
  • removes stored report/session/screenshot artifacts before deleting the database record
  • does not cancel an in-progress run

Example:

curl -X DELETE https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id> \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "success": true,
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "deleted": {
    "test_run": true,
    "storage_objects": 4,
    "storage_paths": [
      "user_example_com/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/example_reject_all_US_CA_20260430-120000_tracker_analysis.md",
      "user_example_com/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/example_reject_all_US_CA_20260430-120000_session.json",
      "user_example_com/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/screenshot.png",
      "user_example_com/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/example_reject_all_US_CA_20260430-120000_compliance_summary.html"
    ],
    "redis_keys": 1,
    "local_files": 2
  }
}

GET /api/v1/runs

What it does:

  • lists the recent persisted runs for the API key owner

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

[
  {
    "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "user_email": "user@example.com",
    "website": "https://example.com",
    "flow": "reject_all",
    "state_code": "US-CA",
    "created_at": "2026-03-19T15:40:12.000000",
    "md_path": "user_example_com/9c33.../example_com_reject_all_US_CA_20260319-154012_tracker_analysis.md",
    "json_path": "user_example_com/9c33.../example_com_reject_all_US_CA_20260319-154012_session.json",
    "bucket": "runs",
    "links": {
      "status": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
      "report": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/report",
      "session": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/session",
      "screenshots": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/screenshots",
      "analysis": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/analysis",
      "live_view": "/live/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
      "results": "/results/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68"
    }
  }
]

GET /api/v1/runs/<session_id>/screenshots

What it does:

  • returns screenshot metadata for a completed run
  • includes browser-usable image URLs that can be rendered directly in HTML
  • only works if the run belongs to the API key owner

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/screenshots \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

[
  {
    "supabase_path": "user/<session_id>/cookie-banner.png",
    "url": "https://...",
    "name": "cookie-banner.png",
    "label": "Initial Privacy Interface",
    "type": "cookie_banner"
  }
]

What good looks like:

  • each item includes a url
  • the returned url can be used directly in an <img src="...">
  • the client does not need a Supabase API key if the URL is already public or pre-signed

GET /api/v1/runs/<session_id>/tracking-data

What it does:

  • returns the detailed tracking markdown artifact for a completed run
  • exposes the request-level evidence now collected for AI summaries, including grouped tracker inventory, interpreted fields, identifiers, consent-signal clues, first-party relay notes, cookies, screenshots, and remediation hints
  • only works if the run belongs to the API key owner
  • returns status: "not_ready" if the run has not finished yet
  • returns 404 if no detailed tracking artifact can be found for the completed run

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/tracking-data \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "status": "completed",
  "content_type": "text/markdown",
  "detailed_tracking": "# Detailed Tracking Evidence\n\n...",
  "source_path": "user_example_com/..._detailed_tracking.md",
  "source_url": "https://...",
  "session_artifact": {
    "detailed_tracking_path": "logs/<session_id>_detailed_tracking.md",
    "detailed_tracking_storage_path": "user_example_com/..._detailed_tracking.md"
  },
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "report": "/api/v1/runs/<session_id>/report",
    "session": "/api/v1/runs/<session_id>/session",
    "screenshots": "/api/v1/runs/<session_id>/screenshots",
    "analysis": "/api/v1/runs/<session_id>/analysis",
    "cipa_analysis": "/api/v1/runs/<session_id>/cipa-analysis"
  }
}

What good looks like:

  • content_type is text/markdown
  • detailed_tracking contains the full detailed evidence artifact
  • source_path identifies the storage or local artifact used
  • source_url is present when the server can resolve a browser-usable storage URL

Example not-ready response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "status": "not_ready",
  "message": "Run must be completed before detailed tracking data can be returned",
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "tracking_data": "/api/v1/runs/<session_id>/tracking-data"
  }
}

GET /api/v1/runs/<session_id>/report

What it does:

  • returns the completed markdown report as text/markdown

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/report \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Output format:

  • plain markdown text
  • same underlying report content you can read in the GUI

What good looks like:

  • the report endpoint returns markdown
  • the same run can also be opened from the web app Results page

GET /api/v1/runs/<session_id>/session

What it does:

  • returns the raw session JSON for a completed run

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/session \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "events": [],
  "screenshots": []
}

GET /api/v1/runs/<session_id>/analysis

What it does:

  • returns the current analysis state for a completed run
  • includes the generated summary HTML once it is available
  • does not start generation by itself
  • may return status: "not_ready" while the run itself is still in progress
  • may return status: "report_not_available" if the run finished without a readable report artifact
  • summary output follows the request language context used by the app, with English as the default

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "status": "completed",
  "summary": "<h3>Applicable Laws & Enforcement</h3><p>...</p><h3>Assessment</h3><ul><li>...</li></ul>",
  "links": {
    "status": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "report": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/report",
    "session": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/session",
    "analysis": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/analysis",
    "live_view": "/live/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "results": "/results/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68"
  }
}

What good looks like:

  • status moves through states like not_ready, report_not_available, not_generated, pending, running, completed, or failed
  • summary is null until generation finishes
  • links.results opens the same run in the web app

Example not-ready response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "status": "not_ready",
  "message": "Run must be completed before analysis can be generated",
  "assessment_mode": "default",
  "links": {
    "status": "/api/v1/runs/<session_id>",
    "analysis": "/api/v1/runs/<session_id>/analysis"
  }
}

POST /api/v1/runs/<session_id>/analysis

What it does:

  • starts background generation for the run analysis
  • returns immediately with a task ID instead of waiting for the summary
  • can force regeneration even if a cached summary already exists
  • accepts a JSON boolean for force_regenerate
  • may return 200 OK with status: "completed" if a cached summary already exists
  • may return status: "not_ready" or status: "report_not_available" if generation cannot start yet

Example:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "force_regenerate": false
  }'

Example queued response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "task_id": "8d1ff6f4-5f86-4faf-bf3a-bbc8f0ea1111",
  "status": "queued",
  "message": "Summary generation started in background",
  "summary": null,
  "links": {
    "status": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "report": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/report",
    "session": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/session",
    "analysis": "/api/v1/runs/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68/analysis",
    "live_view": "/live/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
    "results": "/results/9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68"
  }
}

What good looks like:

  • the request returns quickly with status: "queued" or an in-progress status
  • you poll GET /api/v1/runs/<session_id>/analysis until it returns completed
  • use "force_regenerate": true to rebuild the summary from scratch

GET /api/v1/runs/<session_id>/cipa-analysis

What it does:

  • returns the current got cipa? analysis state for a completed California run
  • uses the CIPA-specific summary mode, separate from the default compliance summary cache
  • does not start generation by itself
  • returns 400 if the run was not performed from California (US-CA or CA)
  • may return status: "not_ready" while the run itself is still in progress
  • may return status: "report_not_available" if the run finished without a readable report artifact
  • summary output follows the request language context used by the app, with English as the default

Example:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/cipa-analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Example response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "status": "completed",
  "assessment_mode": "cipa",
  "summary": "<h3>CIPA Wiretap Matrix</h3><p>...</p>",
  "links": {
    "analysis": "/api/v1/runs/<session_id>/analysis",
    "cipa_analysis": "/api/v1/runs/<session_id>/cipa-analysis",
    "tracking_data": "/api/v1/runs/<session_id>/tracking-data"
  }
}

What good looks like:

  • assessment_mode is cipa
  • status moves through states like not_ready, report_not_available, not_generated, pending, running, completed, or failed
  • use this endpoint only for California runs; non-California runs receive 400

POST /api/v1/runs/<session_id>/cipa-analysis

What it does:

  • starts background generation for got cipa? CIPA-focused analysis
  • is only available for California runs (state set to US-CA or CA when the run was created)
  • does not require or use an assessment_mode field on POST /api/v1/runs
  • can force regeneration even if a cached CIPA summary already exists
  • accepts a JSON boolean for force_regenerate
  • may return 200 OK with status: "completed" if a cached CIPA summary already exists
  • may return status: "not_ready" or status: "report_not_available" if generation cannot start yet

Example:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/<session_id>/cipa-analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "force_regenerate": false
  }'

Example queued response:

{
  "session_id": "9c33bd5a-c3a5-467e-b5b4-4e8f5ddcfa68",
  "task_id": "8d1ff6f4-5f86-4faf-bf3a-bbc8f0ea1111",
  "status": "queued",
  "assessment_mode": "cipa",
  "message": "Summary generation started in background",
  "summary": null
}

What good looks like:

  • the request returns 202 Accepted when generation is queued or already in progress
  • poll GET /api/v1/runs/<session_id>/cipa-analysis until status becomes completed
  • non-California runs receive 400 Bad Request

4. End-To-End Example

Create a run, then poll it:

SESSION_ID=$(curl -s -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "task": "reject_all",
    "state": "US-CA"
  }' | python3 -c "import sys,json; print(json.load(sys.stdin)['session_id'])")

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Then fetch the report:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/report \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Then generate the assessment:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Then poll for it:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY"

For California runs, generate and poll the got cipa? analysis separately:

curl -X POST https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/cipa-analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/cipa-analysis \
  -H "Authorization: Bearer $CONSENT_API_KEY"

Fetch the detailed tracking evidence used by summaries:

curl https://papaya-consent-check-be11a0846ed5.herokuapp.com/api/v1/runs/$SESSION_ID/tracking-data \
  -H "Authorization: Bearer $CONSENT_API_KEY"

5. GUI + Live View

API usage is not separate from the product experience.

If you start a run through the API:

  • the returned links.live_view opens the live browser session in the web app
  • the finished report shows up in your GUI
  • the run shows up under My Tests
  • the report is still available through the Results page

That means developers can automate runs while still using the GUI for investigation and sharing.

6. Errors

Common status codes:

  • 401 Unauthorized: missing or invalid API key
  • 403 Forbidden: inactive subscription for API access
  • 404 Not Found: run not found or not owned by the API key owner
  • 422 or 400: invalid input payload
  • 500: server error