Guna alamat API organisasi anda dan satu kelayakan berskop. Mula dengan satu permintaan baca, semak respons, dan simpan rahsia di luar kawalan sumber dan contoh dokumentasi.
Quire mempunyai satu API awam: REST merentasi HTTPS, diterangkan oleh satu dokumen OpenAPI 3.1, dengan webhook bertandatangan untuk peristiwa dan satu pelayan MCP untuk pembantu AI. Rujukan API menyenaraikan setiap titik akhir dan peristiwa.
Alamat
Setiap organisasi mempunyai alamatnya sendiri, dan API berada di bawahnya:
https://acme.quirelms.com/api/v1/coursesKelayakan menentukan organisasi. Kunci untuk satu organisasi yang digunakan pada alamat organisasi lain ditolak.
Dokumen OpenAPI disajikan di /api/v1/openapi.json pada mana-mata alamat
organisasi, jadi penjana klien sentiasa melihat versi yang anda panggil.
Pengesahan
Kunci API adalah untuk skrip dan integrasi pelayan-ke-pelayan. Seorang
pentadbir menciptanya di /admin/integrations/api-keys, memilih skopnya, dan
melihatnya sekali. Hantarkannya sebagai satu token pembawa:
curl -H "Authorization: Bearer qk_live_..." https://acme.quirelms.com/api/v1/users?limit=50Kunci bermula qk_live_ atau qk_test_. Berikan setiap integrasi kuncinya
sendiri.
OAuth 2.1 adalah untuk aplikasi yang bertindak sebagai seseorang yang sudah log
masuk. Daftarkan satu pelanggan di /admin/integrations/oauth-clients, kemudian
guna aliran kod kebenaran dengan PKCE (/oauth/authorize, /oauth/token), atau
kelayakan pelanggan untuk satu pelanggan mesin. Penemuan berada di
/.well-known/oauth-authorization-server. Satu skop mengehadkan apa yang boleh
dilakukan oleh satu token; ia tidak pernah membenarkannya melakukan lebih daripada
apa yang mampu dilakukan oleh orang itu.
Skop ialah resource:read, resource:write dan resource:delete, contohnya
courses:read atau enrolments:write. Empat daripadanya berkuasa dan dipaparkan
dengan satu amaran pada skrin persetujuan: audit:read, roles:write,
tenants:write dan users:delete.

Permintaan
- Penghalaman: setiap senarai menggunakan penghalaman kursor. Hantar
limit, kemudiannext_cursordaripadapagesebagaicursorselagihas_morebernilai benar (contoh di bawah). Tiada offset. - Perubahan sejak:
updated_sincemengembalikan apa yang berubah selepas satu masa. Pasangkannya denganinclude_deleted=true, atau baca/<resource>/deletions, untuk mengetahui apa yang dibuang. - Pengenal luaran: kebanyakan sumber menerima
external_idanda sendiri, dan/<resource>/ext:{external_id}membaca atau mengemas kini mengikutnya, jadi satu penyegerakan tidak pernah perlu menyimpan pengenal Quire. - Keidempotenan: hantar satu tajuk
Idempotency-KeypadaPOST,PATCHdanDELETE. Satu percubaan semula dengan kunci yang sama memulangkan respons pertama dan bukannya melakukan kerja itu dua kali. Titik akhir pukal memerlukannya. - Versi: versi utama berada dalam laluan (
/v1). Dalamnya, setiap perubahan yang memecahkan ialah satu semakan bertarikh, dipilih dengan tajukQuire-Version, contohnyaQuire-Version: 2026-09-20. Tanpa tajuk itu, anda mendapat semakan yang semasa apabila kelayakan anda dikeluarkan.
Sebuah halaman senarai:
{"data": [...], "page": {"next_cursor": "eyJ2Ijox...", "has_more": true, "limit": 100}}Ralat
Setiap ralat ialah satu dokumen masalah RFC 9457:
{"type": "https://quire.com/errors/enrolment.seat_limit_reached",
"title": "Seat limit reached", "status": 409,
"code": "enrolment.seat_limit_reached", "category": "conflict",
"detail": "The course has no seats left, so this enrolment was not created. ...",
"request_id": "01JB7XQK4Z..."}Cabangkan pada code, yang stabil; detail ditulis untuk manusia, selamat
dipaparkan kepada mereka, dan mungkin berubah. Apabila anda tidak mengecam satu
kod, ketuakan pada category:
| Kategori | Status | Cuba lagi |
|---|---|---|
validation |
422, dengan butiran medan dalam errors |
Tidak |
authentication |
401 | Tidak |
authorization |
403 | Tidak |
not_found |
404 | Tidak |
conflict |
409 | Kadangkala |
precondition |
412 | Tidak |
quota |
402 untuk pelan, 413 untuk saiz | Tidak |
rate_limit |
429, dengan Retry-After |
Ya |
upstream |
502 atau 504 | Ya |
internal |
500 | Ya |
Petik request_id apabila anda menghubungi sokongan.
Webhook
Langgan di /admin/webhooks, atau melalui API di /webhook_subscriptions. Pilih
peristiwa mengikut nama (enrolment.created), mengikut bidang (enrolment.*) atau
semuanya (*). Quire mula-mula menghantar satu webhook.ping; langganan bermula
sebaik sahaja titik akhir anda menjawabnya.
Penghantaran mengikut spesifikasi Standard Webhooks:
POST /hooks/quire
webhook-id: 01JB7XQK4Z8FQ2M3N4P5R6S7T8
webhook-timestamp: 1790000000
webhook-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=Untuk menyahkan satu penghantaran:
- Bina rentetan
{webhook-id}.{webhook-timestamp}.{raw body}daripada bait tepat yang diterima, sebelum sebarang penghuraian JSON. - Kira HMAC-SHA256 ke atasnya dengan rahsia langganan anda, dan base64-kan.
- Bandingkan dengan setiap nilai
v1,dalamwebhook-signaturepada masa pemalar. Mungkin ada dua semasa satu pusingan rahsia; mana-mana yang sepadan adalah sah. - Tolak satu cap masa yang lebih lima minit daripada jam anda.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(secret, id, timestamp, rawBody, header) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = createHmac('sha256', Buffer.from(secret.replace(/^whsec_/, ''), 'base64'))
.update(`${id}.${timestamp}.${rawBody}`).digest();
return header.split(' ').some((part) => {
const [version, value] = part.split(',');
const given = Buffer.from(value ?? '', 'base64');
return version === 'v1' && given.length === expected.length && timingSafeEqual(given, expected);
});
}Nyahganda pada webhook-id: satu penghantaran mungkin tiba lebih daripada sekali.
Badan itu membawa pengenal dan satu ringkasan pendek; ambil sumber tersebut untuk
keadaan semasanya. Penghantaran yang gagal dicuba semula dengan backoff sehingga 72
jam, dan boleh dimainkan semula daripada log penghantaran.
MCP
Pelayan MCP Quire berada di /mcp pada alamat organisasi, merentasi HTTP boleh
strim. Sebuah klien MCP menemui pelayan OAuth daripada
/.well-known/oauth-protected-resource, dan orang itu log masuk dan memberi
persetujuan seperti mana-mana pelanggan OAuth. Alat bertindak sebagai orang itu,
dengan keizinan mereka, dan alat yang memusnahkan meminta pengesahan. Pentadbir
memilih alat mana yang tersedia di /admin/integrations/mcp.

Pelan dan API
Kunci API, pelanggan OAuth, webhook dan pelayan MCP tergolong dalam hak API pelan
tersebut, dan setiap pelan standard menyertainya. Dalam pelan tanpanya, penciptaan
satu kunci, pelanggan atau langganan ditolak, tulisan REST dan sambungan MCP
ditolak, dan bacaan REST terus berfungsi supaya data kekal boleh dieksport. Penolakan
tersebut ialah satu dokumen masalah dengan kod commerce.plan_entitlement, dalam
kategori precondition.
Sambungan
Jenis aktiviti, blok, kaedah pendaftaran, kaedah log masuk, jenis soalan, laporan,
tema dan integrasi milik Quire sendiri diisytiharkan melalui registri sambungan yang
sama yang boleh ditambah oleh sebuah pemasangan kendiri. Sambungan dikompilasi
masuk: tiada pemuat pemalam masa laksana, dan sebuah organisasi hos tidak boleh
menambah satu. Pentadbir menghidupkan atau mematikan setiap sambungan untuk
organisasi mereka di /admin/extensions (lihat
panduan pentadbir).
Untuk menulis satu, mulakan daripada blok sampel dan tema dalam
packages/integration/extensions/src/sample.ts. Pilih titik sambungan dan baca
kontraknya dalam points.ts, kemudian isytiharkan sambungannya dengan satu id,
versi, lesen, apa yang ia sediakan dan perlukan, dan sama ada sebuah organisasi
boleh mematikannya. Daftarkan ia di mana aplikasi web dan pekerja digabungkan,
supaya kedua-duanya bersetuju. Registri menyemak peraturan setiap titik semasa ia
dibina dan setiap kali anda memanggil register, menolak satu set yang akan tidak
sah dengan setiap masalah dinamakan, dan meninggalkan registri tanpa perubahan
apabila ia berbuat demikian. Ujian sambungan itu sendiri sepatutnya menegaskan bahawa
extensionContractProblems kosong baginya dan bahawa mematikannya mengubah apa yang
dipengaruhinya.