{
  "openapi": "3.1.0",
  "info": {
    "title": "QuizBase API",
    "version": "1.0.0",
    "description": "Multilingual trivia API: 1.4M+ quiz-ready questions blended from 11 open-licensed sources, English and Polish at launch, transparent licensing on every record.",
    "contact": {
      "name": "QuizBase",
      "email": "maciej.dzierzek@gmail.com"
    },
    "license": {
      "name": "API: proprietary; Content: per-record (CC-BY, CC-BY-SA, MIT)"
    }
  },
  "servers": [
    {
      "url": "https://quizbase.runriva.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKey": []
    },
    {
      "BearerKey": []
    }
  ],
  "tags": [
    {
      "name": "Questions",
      "description": "Quiz content — list, random, by id."
    },
    {
      "name": "Discovery",
      "description": "Categories, topics, tags, subcategories, languages, stats."
    },
    {
      "name": "Account",
      "description": "Authenticated key info and usage."
    },
    {
      "name": "Reports",
      "description": "Public problem reports (no key required)."
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key (`qb_pk_*` publishable / `qb_sk_*` secret). Also accepted via `Authorization: Bearer <key>`."
      },
      "BearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Same key as `ApiKey`, passed via Authorization header."
      }
    },
    "schemas": {
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Absolute URL identifying the error class.",
            "example": "https://quizbase.runriva.com/errors/invalid_query_param"
          },
          "title": {
            "type": "string",
            "example": "Invalid query parameters"
          },
          "status": {
            "type": "integer",
            "example": 400
          },
          "detail": {
            "type": "string",
            "example": "lang: lang \"xyz\" is not supported. Supported: en, pl"
          },
          "instance": {
            "type": "string",
            "example": "/api/v1/categories?lang=xyz"
          },
          "code": {
            "type": "string",
            "example": "invalid_query_param"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "path",
                "message"
              ]
            },
            "description": "Per-field validation errors (400 only)."
          },
          "retryAfter": {
            "type": "integer",
            "description": "Seconds to wait before retrying (429 only).",
            "example": 3600
          },
          "upgradeUrl": {
            "type": "string",
            "description": "URL to upgrade plan (429 only)."
          },
          "limit": {
            "type": "integer",
            "description": "Rate limit ceiling that was exceeded (429 only).",
            "example": 5
          },
          "tier": {
            "type": "string",
            "description": "API tier whose limit was exceeded (429 only).",
            "example": "free"
          },
          "current": {
            "type": "integer",
            "description": "Number of requests in current window (429 only).",
            "example": 100
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code"
        ]
      },
      "Question": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "019dd2af-1e86-7991-ae22-3dc3dc5e9b2c"
          },
          "text": {
            "type": "string",
            "example": "Jaka jest stolica Polski?"
          },
          "correctAnswer": {
            "type": "string",
            "example": "Warszawa"
          },
          "incorrectAnswers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "Kraków",
              "Gdańsk",
              "Wrocław"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "multiple",
              "boolean",
              "text_input"
            ],
            "example": "multiple"
          },
          "difficulty": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "easy",
              "medium",
              "hard",
              null
            ],
            "example": "easy"
          },
          "language": {
            "type": "string",
            "example": "pl"
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "subcategories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SlugLabel"
            },
            "description": "Localized `{slug, label}` per `?lang=`."
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SlugLabel"
            },
            "description": "Localized `{slug, label}` per `?lang=`."
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "pl"
            ]
          },
          "attribution": {
            "$ref": "#/components/schemas/Attribution"
          },
          "translationOf": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Direct parent (usually English source) when this is a translation."
          },
          "rootQuestionId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Canonical source across translation chains."
          },
          "translator": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "machine",
              "human",
              "native",
              null
            ],
            "description": "Translation provenance. `null` for original-language records."
          },
          "explanation": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional explanation of the correct answer."
          },
          "extensions": {
            "type": "object",
            "additionalProperties": {},
            "description": "Forward-compatible container for stable per-source extras. Today exposes `subcategories: string[]` (also surfaced as the typed top-level `subcategories` field). Future stable fields land here additively."
          },
          "createdAt": {
            "type": "string",
            "example": "2026-04-28T06:03:05.191Z"
          },
          "updatedAt": {
            "type": "string",
            "example": "2026-05-01T09:16:41.496Z"
          }
        },
        "required": [
          "id",
          "text",
          "correctAnswer",
          "incorrectAnswers",
          "type",
          "difficulty",
          "language",
          "category",
          "subcategories",
          "tags",
          "regions",
          "attribution",
          "translationOf",
          "rootQuestionId",
          "translator",
          "explanation",
          "extensions",
          "createdAt",
          "updatedAt"
        ]
      },
      "CategoryRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 14
          },
          "slug": {
            "type": "string",
            "example": "geography"
          },
          "name": {
            "type": "string",
            "example": "Geography"
          }
        },
        "required": [
          "id",
          "slug",
          "name"
        ]
      },
      "SlugLabel": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "european-capitals"
          },
          "label": {
            "type": "string",
            "example": "European Capitals"
          }
        },
        "required": [
          "slug",
          "label"
        ]
      },
      "Attribution": {
        "type": "object",
        "properties": {
          "author": {
            "type": [
              "string",
              "null"
            ],
            "description": "Upstream contributor or community.",
            "example": "OpenTDB community"
          },
          "source": {
            "type": "string",
            "description": "Source slug.",
            "example": "opentdb"
          },
          "license": {
            "type": "string",
            "description": "Effective applied license (SPDX).",
            "example": "CC-BY-SA-4.0"
          },
          "licenseVersion": {
            "type": [
              "string",
              "null"
            ],
            "description": "Original upstream license version.",
            "example": "4.0"
          },
          "licenseUrl": {
            "type": [
              "string",
              "null"
            ],
            "example": "https://creativecommons.org/licenses/by-sa/4.0/"
          },
          "sourceId": {
            "type": "string",
            "description": "Original upstream id.",
            "example": "opentdb:17243"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link to upstream record.",
            "example": "https://opentdb.com/"
          },
          "modifications": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Our modifications per BY-SA § 3(a)(1)(B). e.g. `translated_pl`, `refined_text`, `quizified`.",
            "example": [
              "translated_pl"
            ]
          },
          "lastModified": {
            "type": "string",
            "description": "ISO timestamp of our last modification.",
            "example": "2026-05-01T09:16:41.496Z"
          }
        },
        "required": [
          "author",
          "source",
          "license",
          "licenseVersion",
          "licenseUrl",
          "sourceId",
          "url",
          "modifications",
          "lastModified"
        ]
      },
      "CategoriesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CategoryEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaCategories"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "CategoryEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 14
          },
          "slug": {
            "type": "string",
            "example": "geography"
          },
          "name": {
            "type": "string",
            "example": "Geografia"
          },
          "opentdbId": {
            "type": [
              "integer",
              "null"
            ],
            "example": 22
          },
          "parentId": {
            "type": [
              "integer",
              "null"
            ],
            "example": null
          }
        },
        "required": [
          "id",
          "slug",
          "name",
          "opentdbId",
          "parentId"
        ]
      },
      "MetaCategories": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 24
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "language",
          "requestId"
        ]
      },
      "StatsResponse": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "example": 1294009
          },
          "byLanguage": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "example": {
              "en": 646194,
              "pl": 647815
            }
          },
          "bySource": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Counts per source slug. Pre-launch may be empty (`{}`) — snapshot pipeline gap.",
            "example": {}
          },
          "byCategory": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsCategoryEntry"
            }
          },
          "byDifficulty": {
            "$ref": "#/components/schemas/StatsByDifficulty"
          },
          "byTopic": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsTopicEntry"
            }
          },
          "byTag": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsTagEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaStats"
          }
        },
        "required": [
          "total",
          "byLanguage",
          "bySource",
          "byCategory",
          "byDifficulty",
          "byTopic",
          "byTag",
          "meta"
        ]
      },
      "StatsCategoryEntry": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "geography"
          },
          "name": {
            "type": "string",
            "example": "geography"
          },
          "count": {
            "type": "integer",
            "example": 146384
          }
        },
        "required": [
          "slug",
          "name",
          "count"
        ]
      },
      "StatsByDifficulty": {
        "type": "object",
        "properties": {
          "easy": {
            "type": "integer",
            "example": 0
          },
          "medium": {
            "type": "integer",
            "example": 0
          },
          "hard": {
            "type": "integer",
            "example": 0
          },
          "unrated": {
            "type": "integer",
            "example": 0
          }
        },
        "required": [
          "easy",
          "medium",
          "hard",
          "unrated"
        ],
        "description": "Difficulty distribution. Pre-launch zero-filled — snapshot pipeline gap."
      },
      "StatsTopicEntry": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "biography"
          },
          "label": {
            "type": "string",
            "example": "Biographies"
          },
          "count": {
            "type": "integer",
            "example": 245103
          }
        },
        "required": [
          "slug",
          "label",
          "count"
        ]
      },
      "StatsTagEntry": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "united-states"
          },
          "label": {
            "type": "string",
            "example": "United States"
          },
          "count": {
            "type": "integer",
            "example": 15281
          }
        },
        "required": [
          "slug",
          "label",
          "count"
        ]
      },
      "MetaStats": {
        "type": "object",
        "properties": {
          "generatedAt": {
            "type": "string",
            "example": "2026-05-05T16:32:09.001Z"
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "generatedAt",
          "language",
          "requestId"
        ]
      },
      "LanguagesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LanguageEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaLanguages"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "LanguageEntry": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "pl"
          },
          "name": {
            "type": "string",
            "example": "Polish"
          },
          "nativeName": {
            "type": "string",
            "example": "Polski"
          },
          "count": {
            "type": "integer",
            "example": 647599
          }
        },
        "required": [
          "code",
          "name",
          "nativeName",
          "count"
        ]
      },
      "MetaLanguages": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 2
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "language",
          "requestId"
        ]
      },
      "TopicsListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TopicEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaTopicsList"
          },
          "_links": {
            "$ref": "#/components/schemas/Links"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "TopicEntry": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "biography"
          },
          "kind": {
            "type": "string",
            "enum": [
              "tag",
              "subcategory"
            ],
            "example": "subcategory"
          },
          "label": {
            "type": "string",
            "example": "Biography"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "biography",
              "biographies"
            ]
          },
          "count": {
            "type": "integer",
            "example": 64977
          }
        },
        "required": [
          "slug",
          "kind",
          "label",
          "aliases",
          "count"
        ]
      },
      "MetaTopicsList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 100
          },
          "total": {
            "type": "integer",
            "example": 2184
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "total",
          "language",
          "requestId"
        ]
      },
      "Links": {
        "type": "object",
        "properties": {
          "next": {
            "type": "string",
            "description": "URL to the next page."
          },
          "prev": {
            "type": "string",
            "description": "URL to the previous page."
          }
        }
      },
      "TopicDetailResponse": {
        "type": "object",
        "properties": {
          "topic": {
            "$ref": "#/components/schemas/TopicEntry"
          },
          "facets": {
            "$ref": "#/components/schemas/TopicFacets"
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TopicSampleQuestion"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaBasic"
          }
        },
        "required": [
          "topic",
          "facets",
          "samples",
          "meta"
        ]
      },
      "TopicFacets": {
        "type": "object",
        "properties": {
          "byCategory": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              },
              "required": [
                "slug",
                "name",
                "count"
              ]
            }
          },
          "byDifficulty": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "byLanguage": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "coOccurringTags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsTagEntry"
            }
          },
          "coOccurringSubcategories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsTagEntry"
            }
          }
        },
        "required": [
          "byCategory",
          "byDifficulty",
          "byLanguage",
          "coOccurringTags",
          "coOccurringSubcategories"
        ]
      },
      "TopicSampleQuestion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "text": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "multiple",
              "boolean",
              "text_input"
            ]
          },
          "difficulty": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "easy",
              "medium",
              "hard",
              null
            ]
          },
          "language": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "text",
          "type",
          "difficulty",
          "language"
        ]
      },
      "MetaBasic": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "language",
          "requestId"
        ]
      },
      "TagsListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RawSlugEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaTagsList"
          },
          "_links": {
            "$ref": "#/components/schemas/Links"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "RawSlugEntry": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "united-states"
          },
          "label": {
            "type": "string",
            "example": "United States"
          },
          "count": {
            "type": "integer",
            "example": 7673
          }
        },
        "required": [
          "slug",
          "label",
          "count"
        ]
      },
      "MetaTagsList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 100
          },
          "total": {
            "type": "integer",
            "example": 87559
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "total",
          "language",
          "requestId"
        ]
      },
      "SubcategoriesListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RawSlugEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaTagsList"
          },
          "_links": {
            "$ref": "#/components/schemas/Links"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "ReportAcceptedResponse": {
        "type": "object",
        "properties": {
          "received": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "reportId": {
            "type": "string",
            "format": "uuid",
            "example": "019df4c5-1234-7abc-9def-0123456789ab"
          },
          "meta": {
            "$ref": "#/components/schemas/MetaReport"
          }
        },
        "required": [
          "received",
          "reportId",
          "meta"
        ]
      },
      "MetaReport": {
        "type": "object",
        "properties": {
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "requestId"
        ]
      },
      "ReportRequest": {
        "type": "object",
        "properties": {
          "questionId": {
            "type": "string",
            "format": "uuid",
            "description": "UUID of the question being reported."
          },
          "questionText": {
            "type": "string",
            "minLength": 10,
            "maxLength": 2000,
            "description": "Question text if no ID available."
          },
          "questionUrl": {
            "type": "string",
            "maxLength": 500,
            "format": "uri",
            "description": "Public URL where the question was seen."
          },
          "type": {
            "type": "string",
            "enum": [
              "translation",
              "factual",
              "inappropriate",
              "attribution",
              "other"
            ],
            "example": "translation"
          },
          "comment": {
            "type": "string",
            "maxLength": 2000,
            "description": "What is wrong, in your own words."
          },
          "reporterEmail": {
            "type": "string",
            "format": "email",
            "description": "Optional follow-up address."
          }
        },
        "required": [
          "type"
        ]
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "key": {
            "$ref": "#/components/schemas/ApiKeyInfo"
          },
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "indie",
              "pro",
              "enterprise"
            ],
            "example": "free"
          },
          "rateLimit": {
            "$ref": "#/components/schemas/RateLimitInfo"
          },
          "monthlyQuota": {
            "$ref": "#/components/schemas/MonthlyQuota"
          },
          "meta": {
            "$ref": "#/components/schemas/MetaMe"
          }
        },
        "required": [
          "key",
          "tier",
          "rateLimit",
          "monthlyQuota",
          "meta"
        ]
      },
      "ApiKeyInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "01J3KXY1ZAB7CQNR8TP4Z9EXMQ"
          },
          "name": {
            "type": "string",
            "example": "Default key"
          },
          "prefix": {
            "type": "string",
            "description": "Masked display value.",
            "example": "qb_pk_••••1234"
          },
          "scope": {
            "type": "string",
            "enum": [
              "pk",
              "sk"
            ],
            "description": "`pk` (publishable, CORS-safe for browsers) or `sk` (secret, backend-only).",
            "example": "pk"
          }
        },
        "required": [
          "id",
          "name",
          "prefix",
          "scope"
        ]
      },
      "RateLimitInfo": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "number",
            "description": "Burst window cap (10s sliding). Shared across all active keys of the user.",
            "example": 10
          },
          "remaining": {
            "type": "number",
            "example": 8
          },
          "resetInSeconds": {
            "type": "integer",
            "example": 7
          },
          "burstPer10s": {
            "type": "integer",
            "example": 10
          },
          "perDay": {
            "type": "integer",
            "example": 500
          }
        },
        "required": [
          "limit",
          "remaining",
          "resetInSeconds",
          "burstPer10s",
          "perDay"
        ]
      },
      "MonthlyQuota": {
        "type": "object",
        "properties": {
          "limit": {
            "type": [
              "integer",
              "null"
            ],
            "example": null
          },
          "used": {
            "type": "integer",
            "example": 0
          },
          "resetsAt": {
            "type": [
              "string",
              "null"
            ],
            "example": null
          }
        },
        "required": [
          "limit",
          "used",
          "resetsAt"
        ]
      },
      "MetaMe": {
        "type": "object",
        "properties": {
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "requestId"
        ]
      },
      "UsageResponse": {
        "type": "object",
        "properties": {
          "summary": {
            "$ref": "#/components/schemas/UsageSummary"
          },
          "series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageDayPoint"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaUsage"
          }
        },
        "required": [
          "summary",
          "series",
          "meta"
        ]
      },
      "UsageSummary": {
        "type": "object",
        "properties": {
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "indie",
              "pro",
              "enterprise"
            ]
          },
          "today": {
            "$ref": "#/components/schemas/UsageWindow"
          },
          "week": {
            "$ref": "#/components/schemas/UsageWindow"
          },
          "month": {
            "$ref": "#/components/schemas/UsageWindow"
          }
        },
        "required": [
          "tier",
          "today",
          "week",
          "month"
        ]
      },
      "UsageWindow": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 142
          },
          "prev": {
            "type": "integer",
            "example": 87
          },
          "delta": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percentage change vs previous equivalent window.",
            "example": 63
          },
          "limit": {
            "type": [
              "integer",
              "null"
            ],
            "example": 500
          },
          "windowStart": {
            "type": "string",
            "example": "2026-05-04"
          },
          "windowEnd": {
            "type": "string",
            "example": "2026-05-04"
          }
        },
        "required": [
          "count",
          "prev",
          "delta",
          "limit",
          "windowStart",
          "windowEnd"
        ]
      },
      "UsageDayPoint": {
        "type": "object",
        "properties": {
          "day": {
            "type": "string",
            "example": "2026-04-28"
          },
          "requests": {
            "type": "integer",
            "example": 87
          },
          "errors": {
            "type": "integer",
            "description": "5xx count (server-side).",
            "example": 0
          },
          "clientErrors": {
            "type": "integer",
            "description": "4xx count (caller-side: 401/429/400/422).",
            "example": 2
          }
        },
        "required": [
          "day",
          "requests",
          "errors",
          "clientErrors"
        ]
      },
      "MetaUsage": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "example": "2026-04-28"
          },
          "to": {
            "type": "string",
            "example": "2026-05-04"
          },
          "days": {
            "type": "integer",
            "example": 7
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "from",
          "to",
          "days",
          "requestId"
        ]
      },
      "QuestionsListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Question"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaPaginated"
          },
          "_links": {
            "$ref": "#/components/schemas/Links"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "MetaPaginated": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Items on this page.",
            "example": 50
          },
          "total": {
            "type": "integer",
            "description": "Total matching items (when `count=exact`).",
            "example": 1294009
          },
          "totalEstimate": {
            "type": "integer",
            "description": "Planner-estimated total (default `count=estimate`).",
            "example": 545379
          },
          "countMode": {
            "type": "string",
            "enum": [
              "estimate",
              "exact",
              "none"
            ],
            "description": "Echo of the `count` query param.",
            "example": "estimate"
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "language",
          "requestId"
        ]
      },
      "QuestionsRandomResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Question"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/MetaRandom"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "MetaRandom": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 5
          },
          "language": {
            "type": "string",
            "description": "Language of the response content.",
            "example": "en"
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique request identifier (also in `X-Request-Id` response header).",
            "example": "127fc6d1-d6fb-4771-b2a7-211a08749e5b"
          }
        },
        "required": [
          "count",
          "language",
          "requestId"
        ]
      },
      "QuestionByIdResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Question"
          },
          "meta": {
            "$ref": "#/components/schemas/MetaBasic"
          }
        },
        "required": [
          "data",
          "meta"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/api/v1/categories": {
      "get": {
        "summary": "List categories",
        "description": "24 top-level categories with localized names.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 23,
          "p95": 31,
          "p99": 45,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance"
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Categories list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoriesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/stats": {
      "get": {
        "summary": "Aggregate dataset stats",
        "description": "Total questions, per-language, per-source, per-category counters. Cached.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 23,
          "p95": 31,
          "p99": 45,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Snapshot table read + 5-minute Redis cache, no live aggregation."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Stats snapshot.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/languages": {
      "get": {
        "summary": "Supported languages",
        "description": "Whitelist of `?lang=` values with native names and counts.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 30,
          "p95": 50,
          "p99": 80,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Small static dataset, no heavy aggregation."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Supported languages.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LanguagesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/topics": {
      "get": {
        "summary": "List curated topics",
        "description": "2,184 curated topics with aliases and counts.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 23,
          "p95": 28,
          "p99": 42,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Pre-aggregated topic counts + 1h response cache."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^\\S(.*\\S)?$"
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "tag",
                "subcategory"
              ]
            },
            "required": false,
            "name": "kind",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Curated topics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopicsListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/topics/{slug}": {
      "get": {
        "summary": "Topic detail with facets",
        "description": "Single topic + facets (byCategory, byDifficulty, byLanguage, coOccurringTags, coOccurringSubcategories) + 3 sample questions.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 50,
          "p95": 60,
          "p99": 80,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Detail with facets + 3 sample questions. Pre-aggregated counts + alias resolution."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
              "description": "Curated topic slug or alias.",
              "example": "star-wars"
            },
            "required": true,
            "description": "Curated topic slug or alias.",
            "name": "slug",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Topic detail.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TopicDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Topic not found.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tags": {
      "get": {
        "summary": "List raw tags",
        "description": "Raw tags with display labels and counts. Threshold ≥5 questions.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 22,
          "p95": 29,
          "p99": 43,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Pre-aggregated counts (≥5 questions per tag) + 1h response cache."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^\\S(.*\\S)?$"
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Raw tags.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagsListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subcategories": {
      "get": {
        "summary": "List raw subcategories",
        "description": "Raw subcategories layer. Threshold ≥5 questions.",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 23,
          "p95": 29,
          "p99": 42,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Pre-aggregated counts (≥5 questions per subcategory) + 1h response cache."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^\\S(.*\\S)?$"
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Raw subcategories.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubcategoriesListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/report": {
      "post": {
        "summary": "Report a problem with a question",
        "description": "Anonymous submission for translation / factual / inappropriate / attribution / other reports. Rate-limited 5/min/IP. No API key required.",
        "tags": [
          "Reports"
        ],
        "security": [],
        "x-performance": {
          "p50": 50,
          "p95": 150,
          "p99": 200,
          "sustainedRps": 5,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Single insert + Redis rate-limit bucket. Public, 5/min/IP."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Report accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportAcceptedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body — provide one of `questionId`, `questionText`, `questionUrl`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Question not found (when `questionId` provided).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (5/min/IP).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "summary": "API key info",
        "description": "Confirms your key, tier, and current rate-limit window. The first endpoint to hit when wiring a new client.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 40,
          "p95": 90,
          "p99": 130,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Auth lookup + locals serialization, no DB read on hit path."
        },
        "responses": {
          "200": {
            "description": "Key info.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/usage": {
      "get": {
        "summary": "30-day usage series",
        "description": "Daily request counts + summary across all your keys.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 50,
          "p95": 100,
          "p99": 150,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "30-day window aggregate."
        },
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90,
              "description": "Trailing days, 1-90.",
              "example": 30
            },
            "required": false,
            "description": "Trailing days, 1-90.",
            "name": "days",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Usage payload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/questions": {
      "get": {
        "summary": "Browse questions (cursor pagination)",
        "description": "Paginated browse with filters and delta-sync via `updated_since`.",
        "tags": [
          "Questions"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 97,
          "p95": 112,
          "p99": 200,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Cursor pagination scales to any catalog size. count=estimate default; count=exact walks the full set."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-04-01T00:00:00.000Z",
              "description": "ISO 8601 datetime — only questions modified after this point."
            },
            "required": false,
            "description": "ISO 8601 datetime — only questions modified after this point.",
            "name": "updated_since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^(?:[1-9]\\d*|[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$"
            },
            "required": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "easy",
                "medium",
                "hard"
              ]
            },
            "required": false,
            "name": "difficulty",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "multiple",
                "boolean",
                "text_input"
              ]
            },
            "required": false,
            "name": "type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "tags",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "tags_any",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "topic",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "topics_any",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "subcategory",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "high"
              ]
            },
            "required": false,
            "name": "quality",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}(?:,[A-Z]{2}){0,9}$"
            },
            "required": false,
            "name": "regions",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "opentdb",
                "opentriviaqa",
                "mkqa",
                "mmlu-prox",
                "wikipedia",
                "community",
                "runriva",
                "ai-generated",
                "purchased",
                "quizbase"
              ]
            },
            "required": false,
            "name": "source",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "CC-BY-SA-4.0",
                "CC-BY-SA-3.0",
                "CC-BY-4.0",
                "MIT",
                "proprietary"
              ]
            },
            "required": false,
            "name": "license",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "estimate",
                "exact",
                "none"
              ]
            },
            "required": false,
            "name": "count",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Questions page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionsListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/questions/random": {
      "get": {
        "summary": "Random questions sample",
        "description": "Up to 50 random questions in the requested language. Filter set identical to `/questions`.",
        "tags": [
          "Questions"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 138,
          "p95": 158,
          "p99": 250,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Broad filter: ~p95 158ms @ 50 RPS. Narrow filter (tags/topic/subcategory): ~p95 ~180ms @ 30 RPS."
        },
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            },
            "required": false,
            "name": "amount",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^(?:[1-9]\\d*|[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$"
            },
            "required": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "easy",
                "medium",
                "hard"
              ]
            },
            "required": false,
            "name": "difficulty",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "multiple",
                "boolean",
                "text_input"
              ]
            },
            "required": false,
            "name": "type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "tags",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "tags_any",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "topic",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*(?:,[a-z0-9]+(?:-[a-z0-9]+)*){0,9}$"
            },
            "required": false,
            "name": "topics_any",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
            },
            "required": false,
            "name": "subcategory",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "high"
              ]
            },
            "required": false,
            "name": "quality",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{2}(?:,[A-Z]{2}){0,9}$"
            },
            "required": false,
            "name": "regions",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "opentdb",
                "opentriviaqa",
                "mkqa",
                "mmlu-prox",
                "wikipedia",
                "community",
                "runriva",
                "ai-generated",
                "purchased",
                "quizbase"
              ]
            },
            "required": false,
            "name": "source",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "CC-BY-SA-4.0",
                "CC-BY-SA-3.0",
                "CC-BY-4.0",
                "MIT",
                "proprietary"
              ]
            },
            "required": false,
            "name": "license",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}(?:,[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})*$"
            },
            "required": false,
            "name": "exclude",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Random sample.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionsRandomResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/questions/{id}": {
      "get": {
        "summary": "Single question by id",
        "description": "Deep link / shareable URL / moderation review.",
        "tags": [
          "Questions"
        ],
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerKey": []
          }
        ],
        "x-performance": {
          "p50": 90,
          "p95": 102,
          "p99": 180,
          "sustainedRps": 50,
          "lastMeasured": "2026-05-07",
          "methodology": "https://quizbase.runriva.com/docs/performance",
          "notes": "Direct id lookup — fastest path in the API."
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "UUID v7 of the question.",
              "example": "019dd2af-1e86-7991-ae22-3dc3dc5e9b2c"
            },
            "required": true,
            "description": "UUID v7 of the question.",
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "pl"
              ],
              "default": "en",
              "description": "Display language for category names + slug labels (subcategories/tags)"
            },
            "required": false,
            "description": "Display language for category names + slug labels (subcategories/tags)",
            "name": "lang",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Question.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionByIdResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, invalid, or revoked API key.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "IP not allowed (per-key allowlist).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Question not found, moderated, de-duplicated, or removed upstream.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See `Retry-After` header.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}