Zum Inhalt sprangen

Entwéckler-Guide

Déi Quire REST API, OAuth, Webhooks, de MCP-Server an Erweiderungen.

Als Markdown weisen

Benotzt d’API-Adress vun Ärer Organisatioun an eng Identifikatioun mat bestëmmte Scopes. Fänkt mat enger Liesdemande un, kontrolléiert d’Äntwert, a bleift mat Geheimnisser ausserhalb vum Source Control an den Exempeler vun der Dokumentatioun.

Quire huet eng eenzeg ëffentlech API: REST iwwer HTTPS, beschriwwen an engem OpenAPI 3.1-Dokument, mat signéierte Webhooks fir Evenementer an engem MCP-Server fir KI-Assistenten. D’API-Referenz list all Endpunkt an all Evenement.

Adressen

All Organisatioun huet hir eegen Adress, an d’API läift do ënner:

https://acme.quirelms.com/api/v1/courses

D’Identifikatioun entscheet d’Organisatioun. En Schlëssel fir eng Organisatioun, deen op der Adress vun enger anerer benotzt gëtt, gëtt refuséiert.

D’OpenAPI-Dokument gëtt ëm /api/v1/openapi.json op der Adress vun all Organisatioun servéiert, sou datt Client-Generatoren ëmmer d’Versioun gesinn, déi Dir urufft.

Authentifikatioun

API-Schlësselen sinn fir Skripten an Integratiounen tëscht Serveren. En Administrator erstellt en ëm /admin/integrations/api-keys, wielt seng Scopes a gesäit en eemol. Schéckt en als Bearer-Token:

curl -H "Authorization: Bearer qk_live_..." https://acme.quirelms.com/api/v1/users?limit=50

Schlësselen ufänken mat qk_live_ oder qk_test_. Gitt all Integratioun hiren eegene Schlëssel.

OAuth 2.1 ass fir Applikatiounen, déi handelen wéi eng Persoun, déi sech aloggt. Registréiert en Client ëm /admin/integrations/oauth-clients, benutzt dunn de Autoriséierungscode-Flow mat PKCE (/oauth/authorize, /oauth/token), oder client credentials fir en Maschinn-Client. D’Discovery ass ëm /.well-known/oauth-authorization-server. E Scope limitéiert, wat e Token därf maachen; en léisst en ni méi maachen, wéi d’Persoun selwer därf.

Scopes sinn resource:read, resource:write an resource:delete, zum Beispill courses:read oder enrolments:write. Véier sinn privilegéiert an ginn mat enger Warnung op der Zoustëmmungssäit geweist: audit:read, roles:write, tenants:write an users:delete.

The API keys page with one key, the person it acts as, its scopes and its status, and a form to create another.
API keys list who each key acts as and what it may reach.

Demanden

  • Paginéierung: all Lëschten hunn Cursor-Paginéierung. Gitt limit, dann de next_cursor vun page als cursor, sou laang has_more wäert ass (Beispill hei drënner). Et gëtt keng Offset.
  • Ännerungen zënter: updated_since gëtt zréck, wat no enger Zäit geännert huet. Koppelt en mat include_deleted=true, oder liest /<resource>/deletions, fir erauszefannen, wat ewechgeholl gouf.
  • Extern Identifikatiounen: déi meescht Ressourcen akzeptéieren Ären eegenen external_id, an /<resource>/ext:{external_id} liest oder schreibt no ihm, sou datt e Sync ni d’Identifikatiounen vun Quire muss späicheren.
  • Idempotenz: schéckt en Idempotency-Key-Header op POST, PATCH an DELETE. En neien Attempt mam selwechte Schlëssel gëtt déi éischt Äntwert zréck, amplaz d’Aarbecht zweemol ze maachen. Bulk-Endpunkter erfuerderen en.
  • Versiouen: d’Haaptversioun ass am Wee (/v1). Bannendrem ass all Ännerung, déi d’Kompatibilitéit briicht, eng datéiert Revisioun, gewielt mam Quire-Version-Header, zum Beispill Quire-Version: 2026-09-20. Ouni de Header kritt Dir déi Revisioun, déi aktuell war, wou Är Identifikatioun erausginn gouf.

Eng Säit vun enger Lëschten:

{"data": [...], "page": {"next_cursor": "eyJ2Ijox...", "has_more": true, "limit": 100}}

Feeler

All Feeler ass e Problem-Dokument no 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..."}

Zweigt no code of, deen stabil ass; detail ass fir Mënsche geschriwwen, sécher fir hinnen ze weisen, a kann se veränneren. Wann Dir e Code net kennt, gruppéiert no category:

Kategorie Status Erëmprobéieren
validation 422, mat Felddetails an errors Nei
authentication 401 Nei
authorization 403 Nei
not_found 404 Nei
conflict 409 Manchmal
precondition 412 Nei
quota 402 fir de Plang, 413 fir d’Gréisst Nei
rate_limit 429, mat Retry-After Jo
upstream 502 oder 504 Jo
internal 500 Jo

Zitéiert request_id, wann Dir Iech bei Support mellt.

Webhooks

Abonniéiert ëm /admin/webhooks, oder iwwer d’API ëm /webhook_subscriptions. Wielt d’Evenementer no Numm (enrolment.created), no Beräich (enrolment.*) oder all (*). Quire schéckt éischte e webhook.ping; d’Abonnement start, sou wéi Äre Endpoint drop äntwert.

D’Liwwerunge folgen der Standard-Webhooks-Spezifikatioun:

POST /hooks/quire
webhook-id: 01JB7XQK4Z8FQ2M3N4P5R6S7T8
webhook-timestamp: 1790000000
webhook-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=

Fir eng Liwwerung ze iwwerpréiwen:

  1. Baut de String {webhook-id}.{webhook-timestamp}.{raw body} aus den exakten Bytes, déi kritt gi sinn, ier iergendeen JSON parsed gëtt.
  2. Rechent HMAC-SHA256 driwwer mat Ärem Abonnement-Geheimnis a base64 et.
  3. Vergläicht mat all v1,-Wäert an webhook-signature an konstanter Zäit. Do kënne zwee stoen wärend enger Rotatioun vum Geheimnis; wat och ëmmer passt, ass valabel.
  4. Refuséiert en Zäitstempel, deen vun Ärer Auer méi wéi fënnef Minutten ewech läit.
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);
  });
}

Deduplizéiert no webhook-id: eng Liwwerung kann méi wéi eng Kéier ukommen. De Body dréit Identifikatiounen an eng kuerz Zesummefassung; holt d’Ressource fir hiren aktuellen Zoustand. Feelgeschloen Liwwerungen ginn mat Backoff bis zu 72 Stonnen erëmprobéiert, a kënne vum Liwwerungslog erëmgespillt ginn.

MCP

De MCP-Server vun Quire ass ëm /mcp op der Adress vun der Organisatioun, iwwer streamable HTTP. E MCP-Client fënnt de OAuth-Server ëm /.well-known/oauth-protected-resource eraus, an d’Persoun mellt sech un a gëtt hir Zoustëmmung, wéi bei all OAuth-Client. Tools handelen wéi dës Persoun, mat hiren Permissionen, a destruktiv Tools froen no enger Bestätegung. Administrateuren entscheeden, wéieng Tools ëm /admin/integrations/mcp disponibel sinn.

The AI assistants page with the server address to give an assistant and a table of the tools it can use.
AI assistants (MCP): the server address, and the tools an assistant may call.

Plang an d’API

API-Schlësselen, OAuth-Clienten, Webhooks an de MCP-Server gehéieren zum API-Recht vum Plang, an all Standardplang ëmfasst en. Op engem Plang ouni en gëtt d’Maache vun engem Schlëssel, Client oder Abonnement refuséiert, Schreiwen iwwer REST an MCP-Verbindungen ginn refuséiert, an Liesen iwwer REST funktionéieren weider, sou datt d’Donnéeën exportéierbar bleiwen. De Refus ass e Problem-Dokument mat dem Code commerce.plan_entitlement, an der Kategorie precondition.

Erweiderungen

D’eegenen Aktivitéitsaarten, Blocken, Aschreiwungsmethoden, Umeldungsmethoden, Froenaaarten, Rapporten, Themen an Integratiounen vun Quire ginn duerch dat selwecht Erweiderungsregister declaréiert, zu dem eng selwer gehostet Installatioun och derbäisetze kann. Erweiderungen ginn mat kompiléiert: et gëtt keng Laufzäit-Plugin-Lader, an eng gehostet Organisatioun kann en net derbäisetzen. Administrateuren schalten all Erweiderung fir hir Organisatioun un oder aus ëm /admin/extensions (kuckt den Guide fir Administrateuren).

Fir eng ze schreiwen, fänkt mat dem Beispill-Block an dem Beispill-Thema an packages/integration/extensions/src/sample.ts. Wielt d’Erweiderungs-Plaz an liest säin Vertrag an points.ts, a declaréiert dunn d’Erweiderung mat enger ID, enger Versioun, enger Lizenz, wat se bitt an wat se brauch, an ob eng Organisatioun se därf ausmaachen. Registréiert se do, wou d’Webapplikatioun an den Worker zesummesatzt ginn, sou datt béid averwane sinn. D’Registratur kontrolléiert d’Regelen vun all Plaz, wann se gebaut gëtt an all Kéier, wann Dir register urufft, refuséiert en Ensemble, deen ongëlteg wär, mat all Problem, dat genannt gëtt, an hält d’Registratur onverännert. D’Tester vun der Erweiderung selwer sollen feststellen, datt extensionContractProblems fir en eidel ass an datt se auszeschalten dat ännert, wat se beaflosst.

Navigatioun

Tippt fir ze sichen…

↑↓ navigéieren↵ auswielenEsc zoumaachen