Nei de ynhâld gean

Hantlieding foar ûntwikkelders

De REST API fan Quire, OAuth, webhooks, de MCP-tsjinner en útwreidingen.

As Markdown besjen

Brûk it API-adres fan dyn organisaasje en in bewiis mei beheinde tagong. Begjin mei in lêsoanfraach, kontrolearje it antwurd en hâld geheimen bûten boarnekoade en dokumintaasjefoarbylden.

Quire hat ien iepenbiere API: REST oer HTTPS, beskreaun troch in OpenAPI 3.1-dokumint, mei ûndertekene webhooks foar barrens en in MCP-tsjinner foar AI-assistinten. De API-referinsje list alle einpunten en barrens.

Adressen

Elke organisaasje hat in eigen adres, en de API stiet dêrûnder:

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

It bewiis bepaalt de organisaasje. In kaai foar ien organisaasje dy’t brûkt wurdt op it adres fan in oare organisaasje, wurdt wegere.

It OpenAPI-dokumint is beskikber op /api/v1/openapi.json op elk organisaasje-adres, sadat clientgenerators altyd de ferzje sjen dy’tsto oanropst.

Ferifikaasje

API-kaaien binne foar skripts en yntegraasjes tusken tsjinners. In behearder makket ien oan op /admin/integrations/api-keys, kiest de scopes en sjocht him ien kear. Stjoer him as bearer-token:

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

Kaaien begjinne mei qk_live_ of qk_test_. Jou elke yntegraasje in eigen kaai.

OAuth 2.1 is foar applikaasjes dy’t hannelje as in oanmelde persoan. Registrearje in client op /admin/integrations/oauth-clients, en brûk dêrnei de authorization-code-flow mei PKCE (/oauth/authorize, /oauth/token) of client credentials foar in masineclient. Untdekking is beskikber op /.well-known/oauth-authorization-server. In scope beheint wat in token dwaan kin; it jout nea mear rjochten as de persoan sels hat.

Scopes binne resource:read, resource:write en resource:delete, bygelyks courses:read of enrolments:write. Fjouwer binne befoarrjochte en krije in warskôging op it tastimmingsskerm: audit:read, roles:write, tenants:write en 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.

Oanfragen

  • Sideferdieling: elke list wurdt mei in cursor ferdield yn siden. Jou limit mei en brûk dêrnei de next_cursor út page as cursor wylst has_more wier is (foarbyld hjirûnder). Der is gjin offset.
  • Feroarings sûnt: updated_since jout werom wat nei in tiidstip feroare is. Kombinearje it mei include_deleted=true of lês /<resource>/deletions om te sjen wat fuorthelle is.
  • Eksterne identifiers: de measte boarnen akseptearje dyn eigen external_id; mei /<resource>/ext:{external_id} kinst op basis dêrfan lêze of bywurkje, sadat in syngronisaasje de Quire-identifiers net hoecht te bewarjen.
  • Idempotinsje: stjoer in Idempotency-Key-koptekst mei by POST, PATCH en DELETE. In opnij besochte oanfraach mei deselde kaai jout it earste antwurd werom ynstee fan it wurk dûbel út te fieren. Bulk-einpunten fereaskje dit.
  • Ferzjes: de haadferzje stiet yn it paad (/v1). Dêryn wurdt elke brekkende feroaring in datearre revyzje dy’tst mei de koptekst Quire-Version kiest, bygelyks Quire-Version: 2026-09-20. Sûnder dy koptekst krijst de revyzje dy’t aktueel wie doe’t dyn bewiis útjûn waard.

In side út in list:

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

Flaters

Elke flater is in RFC 9457-probleemdokumint:

{"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..."}

Stjoer op code, dat stabyl is; detail is foar minsken skreaun, is feilich om sjen te litten en kin feroarje. Ast in koade net werkenst, groepearje op category:

Kategory Status Opnij besykje
validation 422, mei fjilddetails yn errors Nee
authentication 401 Nee
authorization 403 Nee
not_found 404 Nee
conflict 409 Soms
precondition 412 Nee
quota 402 foar it abonnemint, 413 foar grutte Nee
rate_limit 429, mei Retry-After Ja
upstream 502 of 504 Ja
internal 500 Ja

Neam request_id ast kontakt opnimst mei stipe.

Webhooks

Abonnearje op /admin/webhooks of fia de API op /webhook_subscriptions. Kies barrens op namme (enrolment.created), op gebiet (enrolment.*) of allegear (*). Quire stjoert earst in webhook.ping; it abonnemint begjint as dyn einpunt dêrop antwurdet.

Leveringen folgje de Standard Webhooks-spesifikaasje:

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

Om in levering te ferifiearjen:

  1. Bou de tekst {webhook-id}.{webhook-timestamp}.{raw body} út de eksakte bytes dy’t ûntfongen binne, foardatst JSON ferwurkje.
  2. Berekkenje dêr HMAC-SHA256 oer mei it geheim fan dyn abonnemint en set it resultaat om nei base64.
  3. Ferlykje it yn konstante tiid mei elke v1,-wearde yn webhook-signature. By in kaairotaasje kinne der twa wêze; ien oerienkomst is genôch.
  4. Wegerje in tiidstimpel dy’t mear as fiif minuten fan dyn klok ôfwykt.
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);
  });
}

Foarkom dûbele ferwurking op basis fan webhook-id: in levering kin mear as ien kear komme. De ynhâld befettet identifiers en in koarte gearfetting; helje de boarne op foar de aktuele steat. Mislearre leveringen wurde oant 72 oeren mei tanimmende tuskenskoften opnij besocht en kinne út it leveringslogboek opnij spile wurde.

MCP

De MCP-tsjinner fan Quire stiet op /mcp op it organisaasje-adres en brûkt streamable HTTP. In MCP-client ûntdekt de OAuth-tsjinner fia /.well-known/oauth-protected-resource; de persoan meldt him oan en jout tastimming lykas by elke OAuth-client. Ark hannelje mei de tastimmingen fan dy persoan, en foar ferneatigjende ark wurdt befêstiging frege. Behearders kieze beskikbere ark op /admin/integrations/mcp.

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.

Abonneminten en de API

API-kaaien, OAuth-clients, webhooks en de MCP-tsjinner falle ûnder it API-rjocht fan it abonnemint, en elk standert abonnemint befettet dit. Op in abonnemint sûnder dit rjocht kinne kaaien, clients en abonneminten net oanmakke wurde, wurde REST-skriufoanfragen en MCP-ferbiningen wegere, mar bliuwe REST-lêsoanfragen wurkjen sadat gegevens eksportearre kinne wurde. De ôfwizing is in probleemdokumint mei koade commerce.plan_entitlement yn de kategory precondition.

Utwreidingen

De eigen aktiviteitstypen, blokken, ynskriuwmetoaden, oanmeldmetoaden, fraachtypen, rapporten, tema’s en yntegraasjes fan Quire wurde oanjûn fia itselde útwreidingsregister dat in selsbehearde ynstallaasje oanfolje kin. Utwreidingen binne ynboud: der is gjin runtime-pluginlader en in hosted organisaasje kin der gjin tafoegje. Behearders skeakelje elke útwreiding foar de eigen organisaasje yn of út op /admin/extensions (sjoch de hantlieding foar behearders).

Om der ien te skriuwen, begjin mei it foarbyldblok en tema yn packages/integration/extensions/src/sample.ts. Kies it útwreidingspunt en lês it kontrakt yn points.ts; ferklearje dêrnei de útwreiding mei in id, ferzje, lisinsje, wat dy leveret en fereasket en oft in organisaasje dy útskeakelje mei. Registrearje him dêr’t de webapplikaasje en worker gearstald wurde, sadat se it iens binne. It register kontrolearret de regels fan elk útwreidingspunt by it bouwen en elke kear datst register oanropst; it wegeret in ûnjildige set mei fermelding fan elk probleem en lit it register ûnferoare. De eigen tests fan de útwreiding moatte befêstigje dat extensionContractProblems der leech foar is en dat útskeakeljen feroaret wat de útwreiding beynfloedet.

Navigaasje

Typ om te sykjen…

↑↓ navigearje↵ selektearjeEsc slute