REST API
RooQuiz exposes a small, read-only REST API so you can pull your team’s form data into scripts, automations (Zapier, Make, n8n), or your own dashboards. It returns form definitions — title, fields, settings, report config — as plain JSON.
The REST API is account-level and authenticates as your team, not as an individual member. If you want an AI client to operate on your quizzes with natural language instead, see MCP Integration.
How it works
- You authenticate with an account API key (prefix
rqp_acct_) that belongs to a team. - The key can read all forms in that team. It is not tied to a person, so it keeps working when members come and go.
- Only a team owner can create, view, or revoke account API keys.
- The API is read-only and returns form definitions only — it does not expose submissions/responses.
Get an API key
Go to Settings → API Keys (visible to team owners only) and click “Create API key”:
- Give it a name (for recognition, e.g.
Zapier - Production). - After creation, a plaintext key starting with
rqp_acct_is shown.
The plaintext key is shown only once. It cannot be retrieved after you leave the page. Copy it immediately; if lost, you must revoke it and create a new one.
Each team can hold at most 10 keys (including revoked ones). To create more, delete one to free a slot (“revoke” only deactivates — it does not free the slot). Treat a key like a password and never commit it to source control.
Authentication
Send the key as a Bearer token on every request:
Authorization: Bearer rqp_acct_xxx...A personal MCP token (rqp_live_) does not work on the REST API — it returns 401. Use an account API key (rqp_acct_).
Endpoints
The base URL looks like https://your-domain/api/v1.
List forms
GET /api/v1/formsLists every form in the key’s team, newest first.
| Query param | Type | Default | Description |
|---|---|---|---|
scene | string | — | Filter by scene: quiz, random_quiz, scorecard, outcome. |
titleContains | string | — | Fuzzy match on title. |
limit | number | 20 | Items per page (max 100). |
page | number | 1 | Page number. |
curl -H "Authorization: Bearer rqp_acct_xxx..." \
"https://your-domain/api/v1/forms?scene=quiz&limit=20"{
"totalDocs": 12,
"page": 1,
"limit": 20,
"items": [
{
"id": "d983d8d9-...",
"title": "Personality Quiz",
"scene": "outcome",
"language": "en_US",
"publicToken": "h7sbps67",
"shareUrl": "https://your-cairo-domain/a/h7sbps67",
"localization": null,
"isActive": true,
"createdAt": "2026-06-18T11:35:11.468Z",
"updatedAt": "2026-06-18T12:59:42.649Z"
}
]
}Get a form
GET /api/v1/forms/{id}Returns one form’s definition.
| Query param | Type | Default | Description |
|---|---|---|---|
includeFields | boolean | true | Include the fields[] array (questions / page breaks). Pass false to skip for large forms. |
includeReport | boolean | true | Include the report / dimension-analysis config. |
curl -H "Authorization: Bearer rqp_acct_xxx..." \
"https://your-domain/api/v1/forms/d983d8d9-..."{
"id": "d983d8d9-...",
"title": "Personality Quiz",
"scene": "outcome",
"language": "en_US",
"description": null,
"isActive": true,
"publicToken": "h7sbps67",
"shareUrl": "https://your-cairo-domain/a/h7sbps67",
"layout": "card",
"localization": null,
"systemText": null,
"createdAt": "2026-06-18T11:35:11.468Z",
"updatedAt": "2026-06-18T12:59:42.649Z",
"fields": [ /* questions & page breaks */ ],
"report": { /* report / dimension config */ }
}Submissions
Read the responses your team’s forms have collected — leads, answers, scores, report results, and UTM attribution. Ideal for CRM sync, custom dashboards, and automations.
Submissions include respondent PII (email, name, IP). Handle and store them responsibly.
List submissions
GET /api/v1/recordsLists submissions across the team, newest first.
| Query param | Type | Default | Description |
|---|---|---|---|
formId | string | — | Only submissions for this form. |
status | string | — | Report status: pending, processing, completed, failed. |
since | ISO date | — | Only submissions created at/after this time (incremental sync). |
until | ISO date | — | Only submissions created at/before this time. |
limit | number | 20 | Items per page (max 100). |
page | number | 1 | Page number. |
curl -H "Authorization: Bearer rqp_acct_xxx..." \
"https://your-domain/api/v1/records?since=2026-06-01&limit=50"{
"totalDocs": 1500,
"page": 1,
"limit": 50,
"items": [
{
"id": "...",
"serialNumber": 11,
"formId": "d983d8d9-...",
"shareToken": "v2hrpv6d",
"reportUrl": "https://your-cairo-domain/a/md8682rx/records/v2hrpv6d",
"submittedAt": "2026-06-18T12:00:00.000Z",
"updatedAt": "2026-06-18T12:00:05.000Z",
"examinee": {
"id": "...", "examineeId": "TZ4730277148",
"email": "lead@example.com", "name": "Jane", "customData": null
},
"metadata": {
"utmSource": "newsletter", "utmMedium": "email",
"utmCampaign": null, "utmTerm": null, "utmContent": null,
"referrer": "https://..."
},
"data": { "q_email": "lead@example.com", "q_rating": 5 },
"result": {
"status": "completed", "score": 2, "maxScore": 4,
"level": "Good", "outcomeCode": null, "outcomeName": null
}
}
]
}data is keyed by each form field’s code (see a form’s fields[] via the forms endpoint). examinee is null for anonymous submissions. result is a compact summary; the full report is on the detail endpoint.
Get a submission
GET /api/v1/records/{id}Returns one submission with its full report result (reportResult) plus metadata.ip / metadata.userAgent.
curl -H "Authorization: Bearer rqp_acct_xxx..." \
"https://your-domain/api/v1/records/..."{
"id": "...",
"serialNumber": 11,
"formId": "d983d8d9-...",
"shareToken": "v2hrpv6d",
"reportUrl": "https://your-cairo-domain/a/md8682rx/records/v2hrpv6d",
"submittedAt": "...",
"updatedAt": "...",
"examinee": { "id": "...", "email": "lead@example.com", "name": "Jane" },
"metadata": { "ip": "203.0.113.4", "userAgent": "...", "utmSource": "newsletter" },
"data": { /* answers keyed by field code */ },
"reportResult": {
"status": "completed",
"overallAnalysis": { "score": 2, "maxScore": 4, "level": "Good", "summary": "...", "suggestions": "..." },
"dimensionAnalysis": { "title": "...", "radar": [], "items": [] },
"outcome": { "code": null, "name": null, "ranking": null },
"aiSuggestion": { "status": "completed", "content": "..." }
}
}Errors
Errors return a JSON body of the shape { "error": { "code": "...", "message": "..." } }.
| Status | Code | When |
|---|---|---|
401 | unauthorized | Missing, invalid, expired, or revoked key (or a non-account token). |
404 | not_found | The form does not exist or is not in this key’s team. |
400 | bad_request | Invalid parameter (e.g. an unknown scene). |
429 | rate_limited | Rate limit exceeded. |
Rate limits
Each key is limited to 120 requests / minute; exceeding it returns 429. Revoke a key from Settings → API Keys whenever it’s no longer needed — any integration using it loses access immediately.