Skip to Content

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”:

  1. Give it a name (for recognition, e.g. Zapier - Production).
  2. 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/forms

Lists every form in the key’s team, newest first.

Query paramTypeDefaultDescription
scenestringFilter by scene: quiz, random_quiz, scorecard, outcome.
titleContainsstringFuzzy match on title.
limitnumber20Items per page (max 100).
pagenumber1Page 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 paramTypeDefaultDescription
includeFieldsbooleantrueInclude the fields[] array (questions / page breaks). Pass false to skip for large forms.
includeReportbooleantrueInclude 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/records

Lists submissions across the team, newest first.

Query paramTypeDefaultDescription
formIdstringOnly submissions for this form.
statusstringReport status: pending, processing, completed, failed.
sinceISO dateOnly submissions created at/after this time (incremental sync).
untilISO dateOnly submissions created at/before this time.
limitnumber20Items per page (max 100).
pagenumber1Page 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": "..." } }.

StatusCodeWhen
401unauthorizedMissing, invalid, expired, or revoked key (or a non-account token).
404not_foundThe form does not exist or is not in this key’s team.
400bad_requestInvalid parameter (e.g. an unknown scene).
429rate_limitedRate 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.

Last updated on