RooQuiz Docs
Integrations & API

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 — and the submissions each form has collected, 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: it returns form definitions and submissions, and cannot create, change or delete anything.

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.

OpenAPI spec

The full machine-readable description of every endpoint is published as an OpenAPI 3.1 document at:

GET /api/v1/openapi.json

It needs no API key and contains no secrets, so you can load it straight into Postman, Insomnia or a client generator. Team owners can also click Open API Debugger on the API Keys page to try the endpoints in the browser.

List forms

GET /api/v1/forms

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

Query paramTypeDefaultDescription
scenestring—Filter by scene: knowledge_quiz, random_knowledge_quiz, scored_quiz, outcome_quiz.
titleContainsstring—Fuzzy match on title.
limitnumber20Items per page (max 100).
pagenumber1Page number.
curl -H "Authorization: Bearer rqp_acct_xxx..." \
  "https://your-domain/api/v1/forms?scene=knowledge_quiz&limit=20"
{
  "totalDocs": 12,
  "page": 1,
  "limit": 20,
  "items": [
    {
      "id": "d983d8d9-...",
      "title": "Personality Quiz",
      "scene": "outcome_quiz",
      "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_quiz",
  "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
formIdstring—Only submissions for this form.
statusstring—Report status: pending, processing, completed, failed.
sinceISO date—Only submissions created at/after this time (incremental sync).
untilISO date—Only 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": "[email protected]", "name": "Jane", "customData": null
      },
      "metadata": {
        "utmSource": "newsletter", "utmMedium": "email",
        "utmCampaign": null, "utmTerm": null, "utmContent": null,
        "referrer": "https://..."
      },
      "data": { "q_email": "[email protected]", "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": "[email protected]", "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 }
  }
}

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.

On this page