---
title: "Phau ntawv qhia tsim kho"
description: "Quire REST API, OAuth, webhooks, MCP server thiab extensions."
image: "https://docs.quirelms.com/og.png"
---

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

# Phau ntawv qhia tsim kho

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

Siv chaw nyob API ntawm koj lub koom haum thiab ntaub ntawv nkag uas muaj scope tsim nyog. Pib thov nyeem, xyuas lus teb, thiab khaws cov lus zais kom deb ntawm source control thiab cov piv txwv hauv ntaub ntawv qhia.

Quire muaj ib lub API pej xeem: REST hla HTTPS, piav los ntawm OpenAPI 3.1 document; muaj webhook kos npe rau xwm txheej thiab MCP server rau AI assistant. [API reference](https://docs.quirelms.com/api/) teev txhua endpoint thiab xwm txheej.

## Chaw nyob <!--quire:addresses-->

Txhua lub koom haum muaj nws tus kheej chaw nyob, thiab API nyob hauv qab qhov chaw ntawd:

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

Cov ntaub ntawv nkag txiav txim lub koom haum. Yog siv key ntawm ib lub koom haum rau chaw nyob ntawm lwm lub, yuav raug tsis kam.

OpenAPI document qhib ntawm `/api/v1/openapi.json` ntawm chaw nyob koom haum twg los tau, kom cov cuab yeej tsim client pom version uas koj tab tom hu.

## Kev txheeb xyuas tus neeg <!--quire:authentication-->

**API key** siv rau script thiab kev txuas server-rau-server. Tus thawj coj tsim ntawm `/admin/integrations/api-keys`, xaiv cov scope, thiab pom key ib zaug xwb. Xa nws ua bearer token:

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

Key pib nrog `qk_live_` lossis `qk_test_`. Muab nws tus kheej key rau txhua qhov kev txuas.

**OAuth 2.1** yog rau app uas ua haujlwm sawv cev rau tus neeg nkag lawm. Tso npe client ntawm `/admin/integrations/oauth-clients`, ces siv authorization code flow nrog PKCE (`/oauth/authorize`, `/oauth/token`), lossis client credentials rau tshuab client. Nrhiav discovery ntawm `/.well-known/oauth-authorization-server`. Scope txo tau yam uas token ua tau; nws yeej tsis tso cai ua ntau dua tus neeg ntawd.

Scope yog `resource:read`, `resource:write` thiab `resource:delete`, piv txwv `courses:read` lossis `enrolments:write`. Plaub scope muaj cai siab thiab qhia lus ceeb toom ntawm nplooj pom zoo: `audit:read`, `roles:write`, `tenants:write` thiab `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>

## Kev thov <!--quire:requests-->

- **Nplooj ntawv**: txhua daim npe muab faib ua nplooj siv cursor. Xa `limit`, ces muab `next_cursor` ntawm `page` ua `cursor` thaum `has_more` tseem yog true (piv txwv hauv qab). Tsis muaj offset.
- **Hloov txij lub sijhawm**: `updated_since` rov qhia yam hloov tom qab lub sijhawm. Siv ua ke nrog `include_deleted=true`, lossis nyeem `/<resource>/deletions`, kom paub yam raug rho tawm.
- **Cim qhia sab nraud**: feem ntau resource txais koj tus kheej `external_id`, thiab `/<resource>/ext:{external_id}` nyeem lossis tsim kho raws tus cim ntawd, kom sync tsis tas khaws Quire tus ID.
- **Ua ib zaug xwb**: xa `Idempotency-Key` header rau `POST`, `PATCH` thiab `DELETE`. Rov thov nrog tib key yuav rov muab thawj qhov lus teb es tsis ua haujlwm dua. Endpoint ntau yam yuav tsum muaj.
- **Version**: version loj nyob hauv path (`/v1`). Hauv version ntawd, txhua qhov hloov rhuav kev sib raug yog revision muaj hnub, xaiv nrog `Quire-Version` header, piv txwv `Quire-Version: 2026-09-20`. Tsis muaj header ces txais revision tam sim no thaum muab ntaub ntawv nkag.

Ib nplooj ntawm daim npe:

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

## Yuam kev <!--quire:errors-->

Txhua qhov yuam kev yog RFC 9457 problem document:

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

Txiav txim raws `code`, uas ruaj; `detail` sau rau neeg nyeem, qhia tau rau tus siv, thiab hloov tau. Yog tsis paub ib code, faib raws `category`:

| Pawg | Xwm txheej | Sim dua |
| --- | --- | --- |
| `validation` | 422, nrog cov teb hauv `errors` | Tsis |
| `authentication` | 401 | Tsis |
| `authorization` | 403 | Tsis |
| `not_found` | 404 | Tsis |
| `conflict` | 409 | Tej zaum |
| `precondition` | 412 | Tsis |
| `quota` | 402 rau phiaj xwm, 413 rau qhov loj | Tsis |
| `rate_limit` | 429, nrog `Retry-After` | Yog |
| `upstream` | 502 lossis 504 | Yog |
| `internal` | 500 | Yog |

Thaum tiv tauj kev pab, qhia `request_id`.

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

Sau npe ntawm `/admin/webhooks`, lossis siv API ntawm `/webhook_subscriptions`. Xaiv xwm txheej raws npe (`enrolment.created`), pawg (`enrolment.*`) lossis txhua yam (`*`). Quire xub xa `webhook.ping`; subscription pib thaum koj endpoint teb nws.

Kev xa ua raws Standard Webhooks specification:

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

Xyuas kev xa:

1. Tsim cov ntawv `{webhook-id}.{webhook-timestamp}.{raw body}` ntawm cov byte uas tau txais kiag, ua ntej parse JSON.
2. Xam HMAC-SHA256 rau nws nrog secret ntawm subscription, ces base64.
3. Piv nrog txhua tus nqi `v1,` hauv `webhook-signature` siv constant time. Thaum hloov secret, muaj tau ob qho; phim ib qho twg yeej siv tau.
4. Tsis txais timestamp uas txawv koj lub moos tshaj tsib feeb.

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

Tsis txhob ua dua raws `webhook-id`: tej zaum ib qho kev xa yuav tuaj ntau zaug. Lub cev muaj ID thiab ntsiab lus luv; thov resource kom tau xwm txheej tam sim no. Kev xa tsis tiav rov sim nrog kev ncua zuj zus ntev txog 72 teev, thiab xa dua tau ntawm daim ntawv teev kev xa.

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

MCP server ntawm Quire nyob ntawm `/mcp` ntawm chaw nyob koom haum, siv streamable HTTP. MCP client nrhiav OAuth server ntawm `/.well-known/oauth-protected-resource`, ces tus neeg nkag thiab pom zoo ib yam li OAuth client. Cov cuab yeej ua haujlwm raws tus neeg ntawd thiab nws cov kev tso cai; cov cuab yeej rhuav tshem nug kom lees paub. Tus thawj coj xaiv cov cuab yeej muaj ntawm `/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>

## Phiaj xwm thiab API <!--quire:plans-and-the-api-->

API key, OAuth client, webhook thiab MCP server yog ib feem ntawm entitlement API hauv phiaj xwm; txhua phiaj xwm qauv muaj qhov ntawd. Yog phiaj xwm tsis muaj, tsim key, client lossis subscription raug tsis kam, REST kev sau thiab kev txuas MCP raug tsis kam, tiam sis REST kev nyeem tseem ua haujlwm kom export tau ntaub ntawv. Qhov tsis kam yog problem document muaj code `commerce.plan_entitlement`, hauv pawg `precondition`.

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

Hom haujlwm, blocks, txoj kev tso npe, txoj kev nkag, hom lus nug, ntaub ntawv qhia, themes thiab kev txuas ntxiv ntawm Quire tau tshaj tawm los ntawm tib extension registry uas qhov kev nruab self-hosted ntxiv tau. Extensions muab compile nrog app: tsis muaj runtime plugin loader, thiab lub koom haum hosting tsis ntxiv tau. Tus thawj coj qhib lossis kaw extension rau nws lub koom haum ntawm `/admin/extensions` (saib [phau ntawv thawj coj](/hmn/admin/extensions/)).

Yuav sau ib qho, pib ntawm sample block thiab theme hauv `packages/integration/extensions/src/sample.ts`. Xaiv extension point thiab nyeem daim cog lus hauv `points.ts`, ces tshaj tawm extension nrog ID, version, licence, yam uas nws muab thiab xav tau, thiab seb lub koom haum kaw tau los tsis tau. Tso npe rau qhov chaw uas web application thiab worker muab sib dhos, kom ob sab pom zoo ib yam. Registry xyuas txhua point cov cai thaum tsim thiab txhua zaus hu `register`, tsis txais ib pawg uas siv tsis tau thiab qhia txhua qhov teeb meem, ces cia registry nyob qub. Kev xeem rau extension yuav tsum xyuas tias `extensionContractProblems` tsis muaj teeb meem rau nws thiab tias tua extension hloov yam uas nws cuam tshuam.

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