---
title: "Programista gvidilo"
description: "La REST-API de Quire, OAuth, webhooks, MCP-servilo kaj kromprogramoj."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/eo/llms.txt
> Use this file to discover all available pages before exploring further.

# Programista gvidilo

<span id="developer-guide"></span>

Uzu la API-adreson de via organizaĵo kaj legitimilon kun limigitaj ampleksoj. Komencu per legpeto, kontrolu la respondon kaj tenu sekretojn ekster fontkontrolo kaj dokumentaj ekzemploj.

Quire havas unu publikan API-on: REST per HTTPS, priskribitan de OpenAPI 3.1-
dokumento, kun subskribitaj webhooks por eventoj kaj MCP-servilo por AI-
helpantoj. La [API-referenco](https://docs.quirelms.com/api/) listigas ĉiun finpunkton kaj eventon.

## Adresoj <!--quire:addresses-->

Ĉiu organizaĵo havas propran adreson kaj la API troviĝas sub ĝi:

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

Legitimilo determinas la organizaĵon. Ŝlosilo de unu organizaĵo uzata ĉe
adreso de alia estas rifuzata.

La OpenAPI-dokumento servas ĉe `/api/v1/openapi.json` ĉe ĉies
organizaĵa adreso, do klientgeneratoroj ĉiam vidas la version vokatan de vi.

## Aŭtentigo <!--quire:authentication-->

**API-ŝlosiloj** estas por skriptoj kaj servilo-al-servilaj integriĝoj. Administranto
kreas unu ĉe `/admin/integrations/api-keys`, elektas ĝiajn ampleksojn
kaj vidas ĝin unufoje. Sendu ĝin kiel bearer-ĵetonon:

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

Ŝlosiloj komenciĝas per `qk_live_` aŭ `qk_test_`. Donu apartan ŝlosilon al ĉiu integriĝo.

**OAuth 2.1** estas por aplikaĵoj agantaj nome de ensalutinta persono. Registru
klienton ĉe `/admin/integrations/oauth-clients`, poste uzu rajtig-kodan
fluon kun PKCE (`/oauth/authorize`, `/oauth/token`) aŭ klientajn
legitimaĵojn por maŝinkliento. Malkovro troviĝas ĉe
`/.well-known/oauth-authorization-server`. Amplekso limigas tion, kion ĵetono povas
fari; ĝi neniam donas pli da rajtoj ol havas la persono.

Ampleksoj estas `resource:read`, `resource:write` kaj `resource:delete`, ekzemple
`courses:read` aŭ `enrolments:write`. Kvar havas specialajn privilegiojn kaj aperas
kun averto en konsenta ekrano: `audit:read`, `roles:write`,
`tenants:write` kaj `users:delete`.

<figure class="quire-shot" lang="en" dir="ltr"><img src="/screenshots/admin-api-keys.webp" alt="The API keys page with one key, the person it acts as, its scopes and its status, and a form to create another." width="944" height="700" loading="lazy" decoding="async"><figcaption>API keys list who each key acts as and what it may reach.</figcaption></figure>

## Petoj <!--quire:requests-->

- **Paĝigo**: ĉiu listo estas paĝigita per kurzoro. Sendu `limit`, poste la
  `next_cursor` de `page` kiel `cursor` dum `has_more` estas vera (ekzemplo
  sube). Ne ekzistas offset.
- **Ŝanĝoj ekde tiam**: `updated_since` redonas ŝanĝojn post difinita tempo.
  Kombinu ĝin kun `include_deleted=true`, aŭ legu `/<resource>/deletions` por
  scii kio estis forigita.
- **Eksteraj identigiloj**: plej multaj rimedoj akceptas propran `external_id`,
  kaj `/<resource>/ext:{external_id}` legas aŭ enmetas/ĝisdatigas laŭ ĝi, do sinkronigo
  neniam bezonas konservi identigilojn de Quire.
- **Idempotenteco**: sendu `Idempotency-Key`-titolon ĉe `POST`, `PATCH` kaj
  `DELETE`. Ripeto kun sama ŝlosilo redonas unuan respondon anstataŭ
  fari la laboron dufoje. Pograndaj finpunktoj postulas ĝin.
- **Versioj**: ĉefa versio estas en vojo (`/v1`). Ene de ĝi ĉiu
  rompa ŝanĝo estas datita revizio elektata per titolo `Quire-Version`, ekzemple
  `Quire-Version: 2026-09-20`. Sen titolo, vi ricevas
  revizion aktualan kiam via legitimilo estis eldonita.

Unu paĝo de listo:

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

## Eraroj <!--quire:errors-->

Ĉiu eraro estas problemdokumento 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..."}
```

Kondutu laŭ `code`, kiu estas stabila; `detail` estas homlegebla, sekure
montrata kaj ŝanĝebla. Se vi ne rekonas kodon, grupigu laŭ `category`:

| Kategorio | Stato | Reprovi |
| --- | --- | --- |
| `validation` | 422, kampaj detaloj en `errors` | Ne |
| `authentication` | 401 | Ne |
| `authorization` | 403 | Ne |
| `not_found` | 404 | Ne |
| `conflict` | 409 | Foje |
| `precondition` | 412 | Ne |
| `quota` | 402 por plano, 413 por grando | Ne |
| `rate_limit` | 429, kun `Retry-After` | Jes |
| `upstream` | 502 aŭ 504 | Jes |
| `internal` | 500 | Jes |

Citigu `request_id` kiam vi kontaktas subtenon.

## Webhooks <!--quire:webhooks-->

Abonu ĉe `/admin/webhooks` aŭ per API ĉe
`/webhook_subscriptions`. Elektu eventojn laŭ nomo (`enrolment.created`),
areo (`enrolment.*`) aŭ ĉiujn (`*`). Quire unue sendas `webhook.ping`; la
abono komenciĝas kiam via finpunkto respondas.

Liveroj sekvas la specifon Standard Webhooks:

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

Por kontroli liveron:

1. Konstruu la ĉenon `{webhook-id}.{webhook-timestamp}.{raw body}` el la
   precizaj ricevitaj bajtoj, antaŭ ajna JSON-analizo.
2. Kalkulu HMAC-SHA256 de ĝi per la sekreto de via abono, kaj kodu ĝin base64.
3. Komparu en konstanta tempo kun ĉiu `v1,`-valoro en `webhook-signature`.
   Dum sekreta rotacio povas esti du; kongruo kun unu validas.
4. Rifuzu tempindikilon pli ol kvin minutojn for de via horloĝo.

```
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);
  });
}
```

Dedukupliku laŭ `webhook-id`: livero povas alveni plurfoje. Korpo portas
identigilojn kaj mallongan resumon; prenu rimedon por ĝia aktuala
stato. Malsukcesaj liveroj estas reprovatataj kun kreskanta atendado ĝis 72 horoj kaj
reprezenteblas el liverprotokolo.

## MCP <!--quire:mcp-->

La MCP-servilo de Quire troviĝas ĉe `/mcp` en la organizaĵa adreso per
streamable HTTP. MCP-kliento malkovras OAuth-servilon ĉe
`/.well-known/oauth-protected-resource`; persono ensalutas kaj
konsentas kiel ĉe ĉiu OAuth-kliento. Iloj agas kun la permesoj de tiu persono,
kaj detruaj iloj petas konfirmon. Administrantoj elektas disponeblajn ilojn ĉe
`/admin/integrations/mcp`.

<figure class="quire-shot" lang="en" dir="ltr"><img src="/screenshots/admin-mcp.webp" alt="The AI assistants page with the server address to give an assistant and a table of the tools it can use." width="944" height="700" loading="lazy" decoding="async"><figcaption>AI assistants (MCP): the server address, and the tools an assistant may call.</figcaption></figure>

## Planoj kaj API <!--quire:plans-and-the-api-->

API-ŝlosiloj, OAuth-klientoj, webhooks kaj MCP-servilo apartenas al la API-rajto de plano,
inkluzivita en ĉiu norma plano. Ĉe plano sen ĝi, kreado de ŝlosilo, kliento aŭ abono estas rifuzata, REST-skriboj kaj MCP-konektoj estas
rifuzataj, sed REST-legoj plu funkcias por ke datumoj restu eksporteblaj. Rifuzo estas problemdokumento kun
kodo `commerce.plan_entitlement` en kategorio `precondition`.

## Kromprogramoj <!--quire:extensions-->

Propraj aktivecotipoj, blokoj, aliĝmetodoj, ensalutmetodoj, demandotipoj,
raportoj, etosoj kaj integriĝoj de Quire estas deklarataj per sama kromprograma
registro, kiun memgastigata instalado povas etendi. Kromprogramoj estas kompilitaj:
ne ekzistas rultempa ŝargilo kaj gastigita organizaĵo ne povas aldoni unu.
Administrantoj ŝaltas aŭ malŝaltas ĉiun kromprogramon por sia organizaĵo ĉe
`/admin/extensions` (vidu [administrantan gvidilon](/eo/admin/extensions/)).

Por verki kromprogramon, komencu per ekzempla bloko kaj etoso en
`packages/integration/extensions/src/sample.ts`. Elektu etendopunkton kaj
legu ĝian kontrakton en `points.ts`, poste deklaru kromprogramon kun ID, versio,
licenco, liverataĵoj kaj bezonataĵoj, kaj ĉu organizaĵo rajtas ĝin malŝalti.
Registru ĝin kie kunmetiĝas retaplikaĵo kaj worker, por ke ambaŭ kongruu. Registro kontrolas proprajn regulojn de ĉiu punkto ĉe konstruo kaj ĉiufoje kiam oni
vokas `register`; ĝi rifuzas nevalidan aron nomante ĉiun problemon kaj
lasas registron senŝanĝa. Testoj de kromprogramo kontrolu ke
`extensionContractProblems` estas malplena por ĝi kaj ke malŝalto ŝanĝas
tio, kion ĝi influas.

Source: https://docs.quirelms.com/eo/developer/index.mdx
