Preskoči na sadržaj

Vodič za razvojne inženjere

Quireov REST API, OAuth, webhookovi, MCP poslužitelj i proširenja.

Prikaži kao Markdown

Upotrijebite API adresu svoje organizacije i vjerodajnicu ograničenog opsega. Započnite zahtjevom za čitanje, provjerite odgovor i držite tajne izvan kontrole izvornog koda i primjera u dokumentaciji.

Quire ima jedan javni API: REST preko HTTPS-a, opisan dokumentom OpenAPI 3.1, potpisane webhookove za događaje i MCP poslužitelj za pomoćnike umjetne inteligencije. Referenca API-ja navodi svaku krajnju točku i događaj.

Adrese

Svaka organizacija ima vlastitu adresu, a API se nalazi pod njom:

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

Vjerodajnica određuje organizaciju. Ključ za jednu organizaciju neće biti prihvaćen na adresi druge.

Dokument OpenAPI poslužuje se na /api/v1/openapi.json na adresi bilo koje organizacije, tako da generatori klijenata uvijek vide verziju koju pozivate.

Autentifikacija

API ključevi namijenjeni su skriptama i integracijama poslužitelj-na-poslužitelj. Administrator izrađuje ključ na /admin/integrations/api-keys, bira njegove opsege i vidi ga samo jednom. Pošaljite ga kao bearer token:

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

Ključevi počinju s qk_live_ ili qk_test_. Svakoj integraciji dodijelite zaseban ključ.

OAuth 2.1 namijenjen je aplikacijama koje djeluju u ime prijavljene osobe. Registrirajte klijenta na /admin/integrations/oauth-clients, a zatim upotrijebite tijek koda za autorizaciju s PKCE-om (/oauth/authorize, /oauth/token) ili vjerodajnice klijenta za strojni klijent. Otkrivanje je na /.well-known/oauth-authorization-server. Opseg ograničava mogućnosti tokena; nikad mu ne dopušta više nego što smije sama osoba.

Opsezi su resource:read, resource:write i resource:delete, primjerice courses:read ili enrolments:write. Četiri imaju povišene ovlasti i prikazuju se uz upozorenje na zaslonu pristanka: audit:read, roles:write, tenants:write i 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.

Zahtjevi

  • Paginacija: svi se popisi paginiraju pokazivačem. Pošaljite limit, a zatim next_cursor iz page kao cursor dok je has_more true (primjer je u nastavku). Offset se ne upotrebljava.
  • Promjene od: updated_since vraća promjene nakon vremena. Kombinirajte ga s include_deleted=true ili pročitajte /<resource>/deletions kako biste saznali što je uklonjeno.
  • Vanjski identifikatori: većina resursa prihvaća vaš external_id, a /<resource>/ext:{external_id} dohvaća ili umeće zapis prema njemu, pa sinkronizacija ne mora pohranjivati Quireove identifikatore.
  • Idempotentnost: šaljite zaglavlje Idempotency-Key uz POST, PATCH i DELETE. Ponovljeni zahtjev s istim ključem vraća prvi odgovor umjesto da dvaput obavi posao. Skupne krajnje točke zahtijevaju taj ključ.
  • Verzije: glavna verzija nalazi se u putanji (/v1). Unutar nje svaka promjena koja narušava kompatibilnost zasebna je datirana revizija koju određuje zaglavlje Quire-Version, primjerice Quire-Version: 2026-09-20. Bez zaglavlja dobivate reviziju koja je bila aktualna kad je izdana vaša vjerodajnica.

Stranica popisa:

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

Pogreške

Svaka je pogreška problem-dokument prema RFC-u 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..."}

Granu račvajte prema code, koji je stabilan; detail je namijenjen ljudima, sigurno ga je prikazati i može se promijeniti. Ako ne prepoznajete kôd, razvrstajte prema category:

Kategorija Status Ponovni pokušaj
validation 422, s pojedinostima polja u errors Ne
authentication 401 Ne
authorization 403 Ne
not_found 404 Ne
conflict 409 Ponekad
precondition 412 Ne
quota 402 za plan, 413 za veličinu Ne
rate_limit 429, sa zaglavljem Retry-After Da
upstream 502 ili 504 Da
internal 500 Da

Kada kontaktirate podršku, navedite request_id.

Webhookovi

Pretplatite se na /admin/webhooks ili putem API-ja na /webhook_subscriptions. Odaberite događaje po nazivu (enrolment.created), području (enrolment.*) ili sve (*). Quire najprije šalje webhook.ping; pretplata počinje kada vaša krajnja točka odgovori na njega.

Isporuke slijede specifikaciju Standard Webhooks:

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

Za provjeru isporuke:

  1. Sastavite niz {webhook-id}.{webhook-timestamp}.{raw body} iz točno primljenih bajtova prije bilo kakve obrade JSON-a.
  2. Izračunajte HMAC-SHA256 nad njim pomoću tajne pretplate i kodirajte ga u base64.
  3. U konstantnom vremenu usporedite sa svakom vrijednošću v1, u webhook-signature. Tijekom rotacije tajne mogu postojati dvije; vrijedi bilo koja podudarna vrijednost.
  4. Odbacite vremensku oznaku koja se od vašeg sata razlikuje više od pet minuta.
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);
  });
}

Spriječite duplikate prema webhook-id: isporuka može stići više puta. Tijelo nosi identifikatore i kratak sažetak; dohvatite resurs da biste vidjeli njegovo trenutačno stanje. Neuspjele se isporuke ponovno pokušavaju uz postupno povećanje razmaka do 72 sata, a mogu se i ponovno pokrenuti iz zapisnika isporuka.

MCP

Quireov MCP poslužitelj nalazi se na /mcp na adresi organizacije i koristi HTTP koji podržava streaming. MCP klijent otkriva OAuth poslužitelj preko /.well-known/oauth-protected-resource, a osoba se prijavljuje i daje pristanak kao i svaki drugi OAuth klijent. Alati djeluju s njezinim dozvolama, a destruktivni alati traže potvrdu. Administratori biraju dostupne alate na /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.

Planovi i API

API ključevi, OAuth klijenti, webhookovi i MCP poslužitelj pripadaju API pogodnostima plana, a obuhvaćeni su svakim standardnim planom. U planu bez te pogodnosti odbija se stvaranje ključa, klijenta ili pretplate, kao i REST upisi i MCP veze; REST čitanje ostaje dostupno kako bi se podaci mogli izvesti. Odbijanje je problem-dokument s kôdom commerce.plan_entitlement i kategorijom precondition.

Proširenja

Quireove vrste aktivnosti, blokovi, načini upisa i prijave, vrste pitanja, izvješća, teme i integracije deklariraju se putem istog registra proširenja kojem instalacija koju sami hostate može dodavati proširenja. Proširenja su ugrađena pri kompilaciji: nema učitavača dodataka tijekom rada, a organizacija na hostanoj usluzi ne može dodati proširenje. Administratori uključuju ili isključuju pojedina proširenja za organizaciju na /admin/extensions (pogledajte vodič za administratore).

Za izradu proširenja počnite s oglednim blokom i temom u packages/integration/extensions/src/sample.ts. Odaberite točku proširenja i pročitajte njezin ugovor u points.ts, zatim deklarirajte proširenje s ID-jem, verzijom, licencom, onim što nudi i zahtijeva te podatkom može li ga organizacija isključiti. Registrirajte ga ondje gdje se sastavljaju web-aplikacija i worker kako bi se slagali. Registar provjerava pravila svake točke pri izradi i pri svakom pozivu register, odbija skup koji nije valjan i navodi sve probleme, a registar pritom ostaje nepromijenjen. Testovi proširenja trebali bi potvrditi da je extensionContractProblems za njega prazan i da isključivanje mijenja ono na što utječe.

Navigacija

Upišite za pretraživanje…

↑↓ kretanje↵ odabirEsc zatvaranje