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
- Start background generation for the same assessment-style analysis shown in the Results page
- 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
- Log in to the web app.
- Make sure your account has an active subscription.
- Open
Account. - In the
API Accesssection, clickCreate API Key. - 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 statusisstartedlinks.live_viewopens the same live session in the web app- once complete, the run appears in the GUI under
My Tests
3. Endpoint Reference
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>",
"list_runs": "/api/v1/runs",
"get_run_report": "/api/v1/runs/<session_id>/report",
"get_run_session": "/api/v1/runs/<session_id>/session",
"analyze_run": "/api/v1/runs/<session_id>/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 websitetask: optional, defaults toreject_alltasksupportsaccept_all,reject_all,gpc,granular_preferencesstate: optional, defaults toUS-CAgranular_preference_prompt: advanced optional field, required only whentaskisgranular_preferenceswait_for_debug_url_seconds: optional, lets the API wait briefly for the live debug URL
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",
"analysis": "/api/v1/runs/<session_id>/analysis",
"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",
"analysis": "/api/v1/runs/<session_id>/analysis",
"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",
"live_view": "/live/<session_id>"
}
}
What good looks like:
statuseventually becomescompleted- you can open
links.live_viewin the web app - the run later appears in the GUI under
My Tests
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",
"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>/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
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:
statusmoves through states likenot_generated,pending,running,completed, orfailedsummaryisnulluntil generation finisheslinks.resultsopens the same run in the web app
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
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>/analysisuntil it returnscompleted - use
"force_regenerate": trueto rebuild the summary from scratch
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"
}' | python -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"
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_viewopens 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 key403 Forbidden: inactive subscription for API access404 Not Found: run not found or not owned by the API key owner422or400: invalid input payload500: server error