Saltate à u cuntenutu

Guida per sviluppatori

L'API REST di Quire, OAuth, webhooks, u servitore MCP è l'estensioni.

Vede cum’è Markdown

Aduprate l’indirizzu API di a vostra urganizazione è una credenziale cù permessi limitati. Cuminciate cù una dumanda di lettura, verificate a risposta, è tenite i sicreti fora di u cuntrollu di versione è di l’esempii di ducumentazione.

Quire hà una sola API publica: REST sopra HTTPS, discritta da un ducumentu OpenAPI 3.1, cù webhooks firmati per l’avvenimenti è un servitore MCP per l’assistenti IA. A riferenza API elenca tutti l’endpoint è l’avvenimenti.

Indirizzi

Ogni urganizazione hà u so indirizzu, è l’API hè dispunibule sottu à quellu:

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

A credenziale determina l’urganizazione. Una chjave d’una urganizazione aduprata à l’indirizzu d’un’altra hè ricusata.

U ducumentu OpenAPI hè servutu in /api/v1/openapi.json à l’indirizzu di qualsiasi urganizazione, cusì i generatori di clienti vedenu sempre a versione chì state chjamendu.

Autentificazione

E chjave API sò per i script è l’integrazioni trà servitori. Un amministratore ne crea una in /admin/integrations/api-keys, ne sceglie i permissi, è a vede una sola volta. Mandate la cum’è gettone bearer:

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

E chjave principianu cù qk_live_ o qk_test_. Date à ogni integrazione a so propria chjave.

OAuth 2.1 hè per l’applicazioni chì agiscenu cum’è una persona cunnessa. Registrate un cliente in /admin/integrations/oauth-clients, dopu aduprate u flussu di codice d’auturizazione cù PKCE (/oauth/authorize, /oauth/token), o e credenziali di cliente per un cliente macchina. A scuperta hè in /.well-known/oauth-authorization-server. Un permessu restringe ciò chì un gettone pò fà; ùn li permette mai di fà di più chè a persona.

I permessi sò resource:read, resource:write è resource:delete, per esempiu courses:read o enrolments:write. Quattru sò privilegiati è mustrati cù un avvirtimentu nantu à u schermu di cunsensu: audit:read, roles:write, tenants:write è users:delete.

Dumande

  • Paginazione: ogni lista hè paginata cù cursori. Passate limit, dopu u next_cursor di page cum’è cursor mentre has_more hè veru (esempiu sottu). Ùn ci hè micca offset.
  • Cambiamenti dapoi: updated_since restituisce ciò chì hè cambiatu dopu à un’ora. Assuciate lu à include_deleted=true, o leghjite /<resource>/deletions, per sapè ciò chì hè statu sguassatu.
  • Identificatori esterni: a maiò parte di e risorse accettanu u vostru external_id, è /<resource>/ext:{external_id} leghje o aghjurna per mezu di quellu, cusì una sincronizazione ùn hà mai bisognu di cunservà l’identificatori di Quire.
  • Idempotenza: mandate un’intestazione Idempotency-Key cù POST, PATCH è DELETE. Una riprova cù a stessa chjave restituisce a prima risposta invece di ripete l’operazione. L’endpoint in lottu l’esigenu.
  • Versioni: a versione maiò hè in u percorsu (/v1). Dentru ella, ogni cambiamentu chì rompe a cumpatibilità hè una revisione datata, scelta cù l’intestazione Quire-Version, per esempiu Quire-Version: 2026-09-20. Senza l’intestazione ricevete a revisione attuale quandu a vostra credenziale hè stata emessa.

Una pagina d’una lista:

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

Errori

Ogni errore hè un ducumentu di prublema 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..."}

Determinate a gestione secondu code, chì hè stabile; detail hè scrittu per e persone, si pò mustà à l’utilizatori, è pò cambià. S’è ùn ricunniscite micca un codice, raggruppate secondu category:

Categoria Statu Riprova
validation 422, cù u dettagliu di u campu in errors Innò
authentication 401 Innò
authorization 403 Innò
not_found 404 Innò
conflict 409 Qualchì volta
precondition 412 Innò
quota 402 per u pianu, 413 per a dimensione Innò
rate_limit 429, cù Retry-After Iè
upstream 502 o 504 Iè
internal 500 Iè

Citate request_id quandu cuntattate u supportu.

Webhooks

Abbonate vi in /admin/webhooks, o per mezu di l’API in /webhook_subscriptions. Sceglite l’avvenimenti per nome (enrolment.created), per area (enrolment.*) o tutti (*). Quire manda prima un webhook.ping; l’ abbonamentu principia quandu u vostru endpoint risponde.

E cunsegne seguitanu a specificazione Standard Webhooks:

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

Per verificà una cunsegna:

  1. Custruite a stringa {webhook-id}.{webhook-timestamp}.{raw body} da i byte esatti ricevuti, prima di analizà ogni JSON.
  2. Calculate HMAC-SHA256 annantu à ella cù u sicretu di l’abbonamentu, è cunvertite u risultatu in base64.
  3. Cunfruntate in tempu custante ogni valore v1, in webhook-signature. Ci ne ponu esse dui durante una rotazione di sicretu; una currispundenza basta.
  4. Ricusate un timestamp chì hè à più di cinque minuti da u vostru clock.
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);
  });
}

Eliminate i duplicati cù webhook-id: una cunsegna pò ghjunghje più d’una volta. U corpu porta identificatori è un riassuntu cortu; scaricate a risorsa per ottene u so statu attuale. E cunsegne fallite sò ritentate cù attese crescenti finu à 72 ore, è ponu esse rimandate da u registru di cunsegne.

MCP

U servitore MCP di Quire hè in /mcp à l’indirizzu di l’urganizazione, via HTTP streamable. Un cliente MCP scopre u servitore OAuth per mezu di /.well-known/oauth-protected-resource, è a persona si cunnette è accunsente cum’è cù qualsiasi cliente OAuth. I strumenti agiscenu cù i permessi di quella persona, è l’azzioni distruttive dumandanu cunferma. L’amministratori sceglienu i strumenti dispunibuli in /admin/integrations/mcp.

Piani è API

E chjave API, i clienti OAuth, i webhooks è u servitore MCP appartenenu à u dirittu API di u pianu, è ogni pianu standard l’include. In un pianu senza quellu dirittu, a creazione d’una chjave, d’un cliente o d’un abbonamentu hè ricusata, e scritture REST è e cunnessioni MCP sò ricusate, è e letture REST cuntinueghjanu à funziunà per chì i dati ferminu esportabili. U rifiutu hè un ducumentu di prublema cù u codice commerce.plan_entitlement, in a categuria precondition.

Estensioni

I tipi d’attività, i blocchi, i metudi d’iscrizzione, i metudi di cunnessione, i tipi di dumanda, i rapporti, i temi è l’integrazioni propii di Quire sò dichjarati attraversu u listessu registru d’estensioni chì una installazione autugestionata pò allargà. L’estensioni sò cumpilate: ùn ci hè micca un caricatore di plugins in esecuzione, è un’urganizazione ospitata ùn ne pò aghjunghje. L’amministratori attivanu o disattivanu ogni estensione per a so urganizazione in /admin/extensions (vede a guida amministrativa).

Per scrive ne una, partite da u bloccu è u tema d’esempiu in packages/integration/extensions/src/sample.ts. Sceglite u puntu d’estensione è leghjite u so cuntrattu in points.ts, dopu dichjarate l’estensione cù un ID, una versione, una licenza, ciò ch’ella furnisce è ciò ch’ella richiede, è s’è un’urganizazione a pò disattivà. Registrate la induve sò cumposti l’applicazione web è u worker, affinch’è tramindui sianu d’accordu. U registru verifica e regule proprie di ogni puntu à a so custruzzione è ogni volta chì chjamate register, ricusa un inseme chì ùn seria micca validu indicendu ogni prublema, è lascia u registru intattu. I testi di l’estensione devenu verificà chì extensionContractProblems sia viotu per ella è chì disattivà la cambi ciò ch’ella influenza.

Navigazione

Scrivite per circà…

↑↓ per navigà↵ per selezziunàEsc per chjude