Gå til indhold

Udviklervejledning

Quires REST-API, OAuth, webhooks, MCP-serveren og udvidelser.

Vis som Markdown

Brug din organisations API-adresse og en legitimationsoplysning med begrænset omfang. Begynd med en læseforespørgsel, kontrollér svaret, og hold hemmeligheder ude af kildekodearkivet og dokumentationseksempler.

Quire har ét offentligt API: REST over HTTPS, beskrevet af et OpenAPI 3.1- dokument, med signerede webhooks til hændelser og en MCP-server til AI- assistenter. API-referencen indeholder alle endpoints og hændelser.

Adresser

Hver organisation har sin egen adresse, og API’et ligger under den:

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

Legitimationsoplysningen afgør organisationen. En nøgle til én organisation, der bruges på en anden organisations adresse, afvises.

OpenAPI-dokumentet leveres på /api/v1/openapi.json på enhver organisationsadresse, så klientgeneratorer altid ser den version, du kalder.

Godkendelse

API-nøgler bruges til scripts og server-til-server-integrationer. En administrator opretter en på /admin/integrations/api-keys, vælger dens omfang og ser den én gang. Send den som et bearer-token:

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

Nøgler begynder med qk_live_ eller qk_test_. Giv hver integration sin egen nøgle.

OAuth 2.1 bruges af applikationer, der handler på vegne af en indlogget person. Registrér en klient på /admin/integrations/oauth-clients, og brug derefter autorisationskodeflowet med PKCE (/oauth/authorize, /oauth/token) eller klientlegitimationsoplysninger til en maskinklient. Discovery findes på /.well-known/oauth-authorization-server. Et scope begrænser, hvad et token kan gøre; det giver det aldrig større rettigheder end personen selv har.

Scopes er resource:read, resource:write og resource:delete, for eksempel courses:read eller enrolments:write. Fire scopes har udvidede rettigheder og vises med en advarsel på samtykkeskærmen: audit:read, roles:write, tenants:write og users:delete.

Forespørgsler

  • Sideopdeling: Alle lister bruger cursor-sideopdeling. Send limit, og send derefter next_cursor fra page som cursor, mens has_more er sand (se eksemplet nedenfor). Der bruges ikke offset.
  • Ændringer siden et tidspunkt: updated_since returnerer det, der er ændret efter et tidspunkt. Kombinér det med include_deleted=true, eller læs /<resource>/deletions for at se, hvad der er fjernet.
  • Eksterne identifikatorer: De fleste ressourcer accepterer din egen external_id, og /<resource>/ext:{external_id} læser eller opretter/opdaterer efter denne, så en synkronisering aldrig behøver at gemme Quires identifikatorer.
  • Idempotens: Send headeren Idempotency-Key med POST, PATCH og DELETE. Et forsøg igen med samme nøgle returnerer det første svar i stedet for at udføre handlingen to gange. Masseendpoints kræver den.
  • Versioner: Hovedversionen står i stien (/v1). Inden for den er hver inkompatibel ændring en dateret revision, valgt med headeren Quire-Version, for eksempel Quire-Version: 2026-09-20. Uden headeren får du den revision, der var aktuel, da din legitimationsoplysning blev udstedt.

En side fra en liste:

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

Fejl

Hver fejl er et RFC 9457-problemdokument:

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

Brug code, som er stabil; detail er skrevet til mennesker, kan vises til dem og kan ændres. Hvis du ikke genkender en kode, skal du gruppere efter category:

Kategori Status Prøv igen
validation 422, med feltoplysninger i errors Nej
authentication 401 Nej
authorization 403 Nej
not_found 404 Nej
conflict 409 Nogle gange
precondition 412 Nej
quota 402 for abonnement, 413 for størrelse Nej
rate_limit 429, med Retry-After Ja
upstream 502 eller 504 Ja
internal 500 Ja

Oplys request_id, når du kontakter support.

Webhooks

Abonnér på /admin/webhooks eller via API’et på /webhook_subscriptions. Vælg hændelser efter navn (enrolment.created), område (enrolment.*) eller alle (*). Quire sender først en webhook.ping; abonnementet starter, når dit endpoint svarer på den.

Leveringer følger specifikationen Standard Webhooks:

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

Sådan kontrolleres en levering:

  1. Byg strengen {webhook-id}.{webhook-timestamp}.{raw body} ud fra de nøjagtige modtagne bytes, før JSON-parsing.
  2. Beregn HMAC-SHA256 af den med abonnementets hemmelighed, og kod resultatet som base64.
  3. Sammenlign i konstant tid med hver v1,-værdi i webhook-signature. Der kan være to under rotation af en hemmelighed; det er gyldigt, hvis en af dem matcher.
  4. Afvis et tidsstempel, der afviger mere end fem minutter fra dit ur.
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);
  });
}

Fjern dubletter efter webhook-id: en levering kan ankomme mere end én gang. Indholdet indeholder identifikatorer og et kort resumé; hent ressourcen for dens aktuelle tilstand. Mislykkede leveringer forsøges igen med stigende ventetid i op til 72 timer og kan afspilles igen fra leveringsloggen.

MCP

Quires MCP-server er på /mcp på organisationens adresse via streamable HTTP. En MCP-klient finder OAuth-serveren via /.well-known/oauth-protected-resource, hvorefter personen logger ind og giver samtykke som for enhver OAuth-klient. Værktøjer handler med personens rettigheder, og destruktive værktøjer beder om bekræftelse. Administratorer vælger, hvilke værktøjer der er tilgængelige på /admin/integrations/mcp.

Abonnementer og API’et

API-nøgler, OAuth-klienter, webhooks og MCP-serveren hører til abonnementets API- rettighed, som indgår i alle standardabonnementer. På et abonnement uden den rettighed afvises oprettelse af nøgler, klienter eller abonnementer; REST-skrivninger og MCP-forbindelser afvises, mens REST-læsninger stadig fungerer, så data kan eksporteres. Afvisningen er et problemdokument med koden commerce.plan_entitlement i kategorien precondition.

Udvidelser

Quires egne aktivitetstyper, blokke, tilmeldingsmetoder, loginmetoder, spørgsmålstyper, rapporter, temaer og integrationer erklæres via det samme udvidelsesregister, som en selvhostet installation kan udvide. Udvidelser kompileres ind: Der findes ingen pluginindlæser under kørsel, og en hostet organisation kan ikke tilføje en. Administratorer slår hver udvidelse til eller fra for deres organisation på /admin/extensions (se administratorvejledningen).

Begynd med eksempelblokken og -temaet i packages/integration/extensions/src/sample.ts, når du skriver en udvidelse. Vælg et udvidelsespunkt, og læs dets kontrakt i points.ts. Deklarér derefter udvidelsen med et id, en version, en licens, hvad den leverer og kræver, og om en organisation må slå den fra. Registrér den dér, hvor webapplikationen og worker sammensættes, så de er enige. Registret kontrollerer hvert udvidelsespunkt efter dets egne regler, når registret bygges, og hver gang du kalder register. Det afviser et ugyldigt sæt med en forklaring af hvert problem og lader registret være uændret. Udvidelsens egne tests bør kontrollere, at extensionContractProblems er tom for den, og at de funktioner, den påvirker, ændres, når den slås fra.

Navigation

Skriv for at søge…

↑↓ naviger↵ vælgEsc luk