quizbase
Skip to content
Command Palette
Search for a command to run...
QuizBase · Docs
by Maciej Dzierżek · published Apr 24, 2026 · updated Jun 15, 2026 · 10 min read · Beginner
languages-and-translations hero illustration
Illustration for: Languages and translations — EN/PL launch coverage · Generated with Nano Banana, brand style

Languages and translations#

QuizBase treats languages as first-class — not as an afterthought. This guide explains what’s available, how translations are sourced, and how ?lang= behaves at the API surface.

Supported languages (at launch)#

CodeLanguageSourceQuality
enEnglishnative (OpenTDB, OpenTriviaQA, MKQA, QuizBase original)ground truth
plPolishmachine translation from English source, prompt-reviewedproduction

Any other value of ?lang= returns 400 invalid_query_param (RFC 9457). If a language you need isn’t here, write to support — we add languages based on actual demand and the table is the source of truth.

Run GET /v1/stats to see exact per-language counts in the live database.

How translations work#

Every question has a language field (ISO 639-1). Translations link back to the source English question via translationOf and share rootQuestionId:

{
  "id": "0193f8b5-7e5c-7c24-9f7a-3d1e1c2a5f10",
  "language": "pl",
  "text": "Jaka jest stolica Polski?",
  "translationOf": "0193f8b5-7e5c-7c24-9f7a-000000000001",
  "rootQuestionId": "0193f8b5-7e5c-7c24-9f7a-000000000001",
  "translator": "machine"
}
  • translationOf — the direct parent id (usually English source)
  • rootQuestionId — the canonical source across translation chains
  • translator — coarse provenance: "machine", "human", "native", or null. The specific upstream system that produced a machine translation is an implementation detail and may change without notice.

Same questions in another language (one call)#

A common need: a user picks a quiz, then switches EN ↔ PL and expects the same questions, not a fresh draw. Draw the set once, keep the ids, then map them to the other language with ids + content_language on GET /v1/questions:

  • ids — up to 250 comma-separated UUIDs (the ids you already hold).
  • content_language — the language of the returned question text (en or pl at launch).

For each id, the sibling record in that language is returned, matched across the translation chain. Ids with no translation come back in meta.missing (so you can keep the original for those) — never dropped silently. Results are ordered to match the ids you sent.

Pass the ids you hold — the server resolves the translation family itself (originals are the root of their chain, so their rootQuestionId is null in responses; you don’t compute roots). The same ids parameter, without content_language, fetches those exact records in one call — handy for anti-repeat or restoring a saved set.

Fallback rules#

GET /v1/questions/random?lang=pl is strict — if we have no matching Polish question for your filters, you get data: [], not an English fallback. This is intentional: mixing languages mid-session breaks the UX of language-specific apps.

If you want fallback behavior, implement it client-side:

Category names — fallback to English#

Unlike questions, category.name does fall back to English when a localization is missing for a supported language. This keeps filter UIs functional even before every category is fully translated:

curl "https://quizbase.runriva.com/api/v1/categories?lang=pl"
# → categories with PL names where translated, English name where not

This is per-field fallback within a supported language — not a fallback for unsupported ?lang= values. Passing ?lang=de still returns 400.

Quality expectations#

  • English — ground truth, human-reviewed where curated
  • Polish — machine-translated from the English source with calibrated trivia-tone prompt and reviewed-on-sample edge cases (quoted film titles preserved, Cyrillic/Ukrainian names transliteration). Watch attribution.source and translator per question for provenance.

Always check attribution.source and translator to judge provenance per question.

See also#