Dokumentasi API

Basis URL: https://quiz.id/api/v1. Semua respons JSON UTF-8 dengan Cache-Control: no-store. Buat token di halaman Profil. API tidak memakai cookie maupun CORS.

Autentikasi

Kirim header Authorization: Bearer qz_.... Tanpa token, token salah/dicabut, akun nonaktif, atau akun belum terverifikasi: 401 unauthorized. Token juga dicabut otomatis saat kata sandi direset. Batas 60 permintaan/menit per token (429 rate_limited disertai header Retry-After).

curl -H "Authorization: Bearer qz_demo_budi_0000000000000000000000000000000000000000" https://quiz.id/api/v1/me

Endpoint

MetodePathKeterangan
GET/meInfo akun + saldo kredit
GET/quizzesDaftar kuis milik sendiri
POST/quizzesBuat kuis (draf, potong 1 kredit). 201 / 403 insufficient_credit
GET/quizzes/{id}Detail kuis + soal (dengan kunci)
PUT/quizzes/{id}Ubah sebagian field: title, description, status, time_limit_minutes, available_from, available_until, shuffle_questions, shuffle_options, allow_retake, show_leaderboard
DELETE/quizzes/{id}Hapus kuis (204)
GET/POST/quizzes/{id}/questionsDaftar / tambah soal
GET/PUT/DELETE/quizzes/{id}/questions/{qid}Lihat / ganti penuh / hapus soal
GET/quizzes/{id}/attemptsRiwayat percobaan semua pemain pada kuis milik sendiri (tanpa email)
GET/quizzes/{id}/attempts/{aid}Detail satu percobaan beserta jawaban per soal (answers bernilai null bila masih berjalan). 404 bila bukan milik kuis ini
DELETE/quizzes/{id}/attempts/{aid}Hapus satu percobaan (pemain dapat bermain lagi bila pengulangan mati); tercatat di log audit. 204 / 404
GET/quizzes/{id}/leaderboardPapan skor kuis milik sendiri: rank, player_name, score_percent, duration_seconds (tanpa email; tetap tersedia walau show_leaderboard mati)

Kuis menyertakan playable (true bila tautan bagikan aktif, bukan draf, dan punya minimal satu soal) dan show_leaderboard (default true: papan skor tampil ke pemain yang sudah menyelesaikan kuis, hanya nama tampilan).

Contoh

Buat kuis dengan timer 5 menit:

curl -X POST https://quiz.id/api/v1/quizzes \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"title":"Kuis API","description":"Dibuat via API","time_limit_minutes":5}'

Jendela waktu main opsional (WIB, format YYYY-MM-DD HH:MM, null/kosong = bebas). available_from tidak boleh setelah available_until (422). Deadline percobaan = yang lebih awal antara timer dan available_until:

curl -X POST https://quiz.id/api/v1/quizzes \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"title":"Kuis Terjadwal","available_from":"2026-11-01 08:00","available_until":"2026-11-01 17:00"}'

Tambah soal pilihan ganda (type: single | multiple):

curl -X POST https://quiz.id/api/v1/quizzes/ID/questions \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"type":"single","prompt":"Ibu kota Indonesia?","options":[{"label":"Jakarta","is_correct":true},{"label":"Bandung","is_correct":false}]}'

Tambah soal angka:

-d '{"type":"number","prompt":"Nilai pi (2 desimal)?","answer":"3.14","tolerance":"0.01"}'

Opsi permainan: shuffle_questions (acak soal), shuffle_options (acak urutan opsi per percobaan), allow_retake (default false: tiap pemain 1 percobaan sampai pemilik menghapus riwayatnya; true: tak terbatas), show_leaderboard (default true).

Gambar soal opsional lewat URL (image_url, hanya http/https, maks 2048 karakter; null/kosong = tanpa gambar; skema lain seperti javascript: atau data: menghasilkan 422):

-d '{"type":"number","prompt":"Bendera apa ini?","image_url":"https://contoh.com/bendera.png","answer":"1"}'

Publikasikan (butuh minimal 1 soal):

curl -X PUT https://quiz.id/api/v1/quizzes/ID \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"status":"public"}'

Papan skor dan detail percobaan:

curl -H "Authorization: Bearer $TOKEN" https://quiz.id/api/v1/quizzes/ID/leaderboard
curl -H "Authorization: Bearer $TOKEN" https://quiz.id/api/v1/quizzes/ID/attempts/AID

Format galat

{"error":{"code":"validation_failed","message":"Data tidak valid.","fields":{"title":"Wajib diisi"}}}

Kode: 400 bad_request (JSON kosong/rusak/bukan objek/terlalu dalam), 401 unauthorized, 403 insufficient_credit, 404 not_found, 405 method_not_allowed (disertai Allow), 413 payload_too_large (isi permintaan maks. 256 KB), 422 validation_failed, 429 rate_limited.