შიგთავსზე გადასვლა

დეველოპერის სახელმძღვანელო

Quire-ის REST API, OAuth, ვებჰუკები, MCP სერვერი და გაფართოებები.

Markdown-ად ნახვა

გამოიყენეთ თქვენი ორგანიზაციის API მისამართი და არეებით შეზღუდული რწმუნებათა სიგელი. დაიწყეთ წაკითხვის მოთხოვნით, შეამოწმეთ პასუხი და საიდუმლოებები წყაროს კონტროლისა და დოკუმენტაციის მაგალითების გარეთ იქონიეთ.

Quire-ს აქვს ერთი საჯარო API: REST HTTPS-ზე, აღწერილი OpenAPI 3.1 დოკუმენტით, ხელმოწერილი ვებჰუკებით მოვლენებისთვის და MCP სერვერით AI ასისტენტებისთვის. API-ის ცნობარი ჩამოთვლის ყველა ენდპოინთსა და მოვლენას.

მისამართები

თითოეულ ორგანიზაციას აქვს საკუთარი მისამართი და API მის ქვეშ ცხოვრობს:

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

ორგანიზაციას რწმუნებათა სიგელი წყვეტს. ერთი ორგანიზაციის გასაღები, რომელიც სხვის მისამართზეა გამოყენებული, უარყოფილია.

OpenAPI დოკუმენტი მიეწოდება /api/v1/openapi.json-ში ნებისმიერი ორგანიზაციის მისამართზე, ასე რომ კლიენტის გენერატორები ყოველთვის ხედავენ ვერსიას, რომელსაც იძახებთ.

ავთენტიფიკაცია

API გასაღებები სკრიპტებისა და სერვერიდან სერვერზე ინტეგრაციებისთვისაა. ადმინისტრატორი ქმნის ერთ-ერთს /admin/integrations/api-keys-ში, ირჩევს მის არეებს და ერთხელ ხედავს მას. გაგზავნეთ ის, როგორც მატარებლის ტოკენი:

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

გასაღებები იწყება qk_live_-ით ან qk_test_-ით. მიეცით თითოეულ ინტეგრაციას საკუთარი გასაღები.

OAuth 2.1 აპლიკაციებისთვისაა, რომლებიც მოქმედებენ, როგორც შესული ადამიანი. დაარეგისტრირეთ კლიენტი /admin/integrations/oauth-clients-ში, შემდეგ გამოიყენეთ ავტორიზაციის კოდის ნაკადი PKCE-ით (/oauth/authorize, /oauth/token) ან კლიენტის რწმუნებათა სიგელები მანქანური კლიენტისთვის. აღმოჩენა არის /.well-known/oauth-authorization-server-ში. არეა ავიწროებს იმას, რისი გაკეთებაც ტოკენს შეუძლია; ის არასდროს აძლევს მას იმაზე მეტის გაკეთების საშუალებას, ვიდრე ადამიანს შეეძლო.

არეებია resource:read, resource:write და resource:delete, მაგალითად courses:read ან enrolments:write. ოთხი პრივილეგირებულია და ნაჩვენებია გაფრთხილებით თანხმობის ეკრანზე: audit:read, roles:write, tenants:write და 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.

მოთხოვნები

  • გვერდები: ყველა სია კურსორითაა დაგვერდებული. გადაეცით limit, შემდეგ next_cursor page-დან, როგორც cursor, სანამ has_more ჭეშმარიტია (მაგალითი ქვემოთ). ოფსეტი არ არსებობს.
  • ცვლილებები დროიდან: updated_since აბრუნებს იმას, რაც დროის შემდეგ შეიცვალა. შეუთავსეთ ის include_deleted=true-ს ან წაიკითხეთ /<resource>/deletions, რომ გაიგოთ, რა წაიშალა.
  • გარე იდენტიფიკატორები: რესურსების უმეტესობა იღებს თქვენს საკუთარ external_id-ს, ხოლო /<resource>/ext:{external_id} კითხულობს ან ქმნის-აახლებს მის მიხედვით, ასე რომ სინქრონიზაციას არასდროს სჭირდება Quire-ის იდენტიფიკატორების შენახვა.
  • იდემპოტენტობა: გაგზავნეთ Idempotency-Key სათაური POST-ზე, PATCH-სა და DELETE-ზე. იმავე გასაღებით ხელახალი ცდა აბრუნებს პირველ პასუხს, სამუშაოს ორჯერ გაკეთების ნაცვლად. მასობრივი ენდპოინთები მას მოითხოვენ.
  • ვერსიები: მთავარი ვერსია მისამართშია (/v1). მის შიგნით ყოველი მტვრევადი ცვლილება დათარიღებული რევიზიაა, არჩეული Quire-Version სათაურით, მაგალითად Quire-Version: 2026-09-20. სათაურის გარეშე იღებთ რევიზიას, რომელიც მოქმედი იყო, როცა თქვენი რწმუნებათა სიგელი გაიცა.

სიის ერთი გვერდი:

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

შეცდომები

ყოველი შეცდომა 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..."}

გადაწყვიტეთ code-ით, რომელიც სტაბილურია; detail დაწერილია ადამიანებისთვის, უსაფრთხოა მათთვის საჩვენებლად და შეიძლება შეიცვალოს. როცა კოდს ვერ ცნობთ, დააჯგუფეთ category-ით:

კატეგორია სტატუსი ხელახალი ცდა
validation 422, ველის დეტალით errors-ში არა
authentication 401 არა
authorization 403 არა
not_found 404 არა
conflict 409 ზოგჯერ
precondition 412 არა
quota 402 გეგმისთვის, 413 ზომისთვის არა
rate_limit 429, Retry-After-ით დიახ
upstream 502 ან 504 დიახ
internal 500 დიახ

მხარდაჭერასთან დაკავშირებისას მიუთითეთ request_id.

ვებჰუკები

გამოიწერეთ /admin/webhooks-ში ან API-ით /webhook_subscriptions-ში. აირჩიეთ მოვლენები სახელით (enrolment.created), არეით (enrolment.*) ან ყველა (*). Quire ჯერ აგზავნის webhook.ping-ს; გამოწერება იწყება, როცა თქვენი ენდპოინთი მას უპასუხებს.

მიწოდებები მიჰყვება Standard Webhooks სპეციფიკაციას:

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

მიწოდების შესამოწმებლად:

  1. ააგეთ სტრიქონი {webhook-id}.{webhook-timestamp}.{raw body} მიღებული ზუსტი ბაიტებიდან, ნებისმიერ JSON გარჩევამდე.
  2. გამოთვალეთ HMAC-SHA256 მასზე თქვენი გამოწერის საიდუმლოთი და გადაიყვანეთ base64-ში.
  3. შეადარეთ თითოეულ v1, მნიშვნელობას webhook-signature-ში მუდმივ დროში. საიდუმლოს როტაციისას შეიძლება ორი იყოს; ორივეს დამთხვევა ვალიდურია.
  4. უარყავით დროის ანიშანი, რომელიც თქვენს საათს ხუთ წუთზე მეტით სცდება.
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);
  });
}

გააორმაგეთ webhook-id-ით: მიწოდება შეიძლება არაერთხელ მოვიდეს. ტანი ატარებს იდენტიფიკატორებსა და მოკლე შეჯამებას; აიღეთ რესურსი მისი ამჟამინდელი მდგომარეობისთვის. წარუმატებელი მიწოდებები ხელახლა ცდება უკან დახევით 72 საათამდე და შეიძლება ხელახლა დაკვრა მიწოდების ჟურნალიდან.

MCP

Quire-ის MCP სერვერია /mcp-ში ორგანიზაციის მისამართზე, ნაკადური HTTP-ზე. MCP კლიენტი აღმოაჩენს OAuth სერვერს /.well-known/oauth-protected-resource-დან, ხოლო ადამიანი შედის და ეთანხმება, როგორც ნებისმიერ OAuth კლიენტთან. ინსტრუმენტები მოქმედებენ, როგორც ის ადამიანი, მათი ნებართვებით, ხოლო დესტრუქციული ინსტრუმენტები დადასტურებას ითხოვენ. ადმინისტრატორები ირჩევენ, რომელი ინსტრუმენტებია ხელმისაწვდომი /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.

გეგმები და API

API გასაღებები, OAuth კლიენტები, ვებჰუკები და MCP სერვერი გეგმის API უფლებამოსილებას ეკუთვნის და ყველა სტანდარტული გეგმა მას მოიცავს. გეგმაზე მის გარეშე გასაღების, კლიენტის ან გამოწერის შექმნა უარყოფილია, REST ჩაწერები და MCP შეერთებები უარყოფილია, ხოლო REST წაკითხვები მუშაობას აგრძელებს, რათა მონაცემები ექსპორტირებადი დარჩეს. უარყოფა პრობლემის დოკუმენტია კოდით commerce.plan_entitlement, კატეგორიაში precondition.

გაფართოებები

Quire-ის საკუთარი აქტივობების ტიპები, ბლოკები, ჩარიცხვის მეთოდები, შესვლის მეთოდები, კითხვის ტიპები, ანგარიშები, თემები და ინტეგრაციები გამოცხადებულია იმავე გაფართოების რეესტრის მეშვეობით, რომელსაც თვითმართვადი ინსტალაცია შეიძლება დაემატოს. გაფართოებები კომპილირებულია: გაშვების დროის მოდულის ჩამტვირთავი არ არსებობს და მასპინძელ ორგანიზაციას ვერ დაამატებს ვერცერთს. ადმინისტრატორები რთავენ ან თიშავენ თითოეულ გაფართოებას თავიანთი ორგანიზაციისთვის /admin/extensions-ში (იხ. ადმინისტრატორის სახელმძღვანელო).

მის დასაწერად დაიწყეთ ნიმუშის ბლოკიდან და თემიდან packages/integration/extensions/src/sample.ts-ში. აირჩიეთ გაფართოების წერტილი და წაიკითხეთ მისი კონტრაქტი points.ts-ში, შემდეგ გამოაცხადეთ გაფართოება id-ით, ვერსიით, ლიცენზიით, იმით, რასაც ის იძლევა და მოითხოვს, და იმით, შეიძლება თუ არა ორგანიზაციამ მისი გამორთვა. დაარეგისტრირეთ ის იქ, სადაც ვებაპლიკაცია და worker-ი კომპონირდება, რათა ორივე შეთანხმდეს. რეესტრი ამოწმებს თითოეული წერტილის საკუთარ წესებს აგებისას და ყოველ ჯერზე, როცა იძახებთ register-ს, უარყოფს ნაკრებს, რომელიც არავალიდური იქნებოდა, ყველა დასახელებული პრობლემით, და რეესტრს უცვლელად ტოვებს, როცა ამას აკეთებს. გაფართოების საკუთარი ტესტები უნდა ამტკიცებდნენ, რომ extensionContractProblems ცარიელია მისთვის და რომ მისი გამორთვა ცვლის იმას, რაზეც ის მოქმედებს.

ნავიგაცია

ძიებისთვის აკრიფეთ…

↑↓ ნავიგაცია↵ არჩევაEsc დახურვა