---
title: "Οδηγός προγραμματιστή"
description: "Το REST API του Quire, OAuth, webhooks, ο διακομιστής MCP και επεκτάσεις."
image: "https://docs.quirelms.com/og.png"
---

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

# Οδηγός προγραμματιστή

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

Χρησιμοποιήστε τη διεύθυνση API του οργανισμού σας και διαπιστευτήριο με περιορισμένα πεδία εφαρμογής. Ξεκινήστε με αίτημα ανάγνωσης, ελέγξτε την απόκριση και κρατήστε τα μυστικά έξω από τον έλεγχο πηγαίου κώδικα και τα παραδείγματα τεκμηρίωσης.

Το Quire διαθέτει ένα δημόσιο API: REST μέσω HTTPS, περιγραφόμενο σε έγγραφο OpenAPI 3.1, υπογεγραμμένα webhooks για συμβάντα και διακομιστή MCP για βοηθούς AI. Η [αναφορά API](https://docs.quirelms.com/api/) παραθέτει κάθε τελικό σημείο και συμβάν.

## Διευθύνσεις <!--quire:addresses-->

Κάθε οργανισμός έχει δική του διεύθυνση και το API βρίσκεται κάτω από αυτή:

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

Το διαπιστευτήριο καθορίζει τον οργανισμό. Ένα κλειδί ενός οργανισμού απορρίπτεται αν χρησιμοποιηθεί στη διεύθυνση άλλου.

Το έγγραφο OpenAPI παρέχεται στο `/api/v1/openapi.json` στη διεύθυνση οποιουδήποτε οργανισμού, ώστε οι γεννήτριες πελατών να βλέπουν πάντα την έκδοση που καλείτε.

## Έλεγχος ταυτότητας <!--quire:authentication-->

Τα **Κλειδιά API** προορίζονται για δέσμες ενεργειών και ενσωματώσεις διακομιστή προς διακομιστή. Ένας διαχειριστής δημιουργεί κλειδί στο `/admin/integrations/api-keys`, επιλέγει τα πεδία εφαρμογής του και το βλέπει μόνο μία φορά. Στείλτε το ως bearer token:

```
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`) ή διαπιστευτήρια πελάτη για πελάτη μηχανής. Η διεύθυνση discovery είναι `/.well-known/oauth-authorization-server`. Ένα πεδίο εφαρμογής περιορίζει τι μπορεί να κάνει ένα token· δεν του επιτρέπει ποτέ περισσότερα από όσα μπορεί να κάνει το ίδιο το άτομο.

Τα πεδία εφαρμογής είναι `resource:read`, `resource:write` και `resource:delete`, για παράδειγμα `courses:read` ή `enrolments:write`. Τέσσερα έχουν προνομιακά δικαιώματα και εμφανίζονται με προειδοποίηση στην οθόνη συναίνεσης: `audit:read`, `roles:write`, `tenants:write` και `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>

## Αιτήματα <!--quire:requests-->

- **Σελιδοποίηση**: κάθε λίστα σελιδοποιείται με δρομέα. Περάστε `limit` και έπειτα το `next_cursor` από το `page` ως `cursor` όσο το `has_more` είναι true (παράδειγμα παρακάτω). Δεν υπάρχει offset.
- **Αλλαγές από τότε**: το `updated_since` επιστρέφει όσα άλλαξαν μετά από μια χρονική στιγμή. Συνδυάστε το με `include_deleted=true` ή διαβάστε το `/<resource>/deletions` για να μάθετε τι αφαιρέθηκε.
- **Εξωτερικά αναγνωριστικά**: οι περισσότερες πηγές δέχονται δικό σας `external_id`, και το `/<resource>/ext:{external_id}` διαβάζει ή εκτελεί upsert με βάση αυτό. Έτσι ένας συγχρονισμός δεν χρειάζεται να αποθηκεύει αναγνωριστικά Quire.
- **Ιδιοδυναμία**: στείλτε κεφαλίδα `Idempotency-Key` στα `POST`, `PATCH` και `DELETE`. Μια επανάληψη με το ίδιο κλειδί επιστρέφει την πρώτη απόκριση αντί να εκτελέσει τη λειτουργία δύο φορές. Τα μαζικά τελικά σημεία το απαιτούν.
- **Εκδόσεις**: η κύρια έκδοση βρίσκεται στη διαδρομή (`/v1`). Σε αυτήν, κάθε ασύμβατη αλλαγή είναι αναθεώρηση με ημερομηνία, η οποία επιλέγεται με την κεφαλίδα `Quire-Version`, για παράδειγμα `Quire-Version: 2026-09-20`. Χωρίς την κεφαλίδα λαμβάνετε την αναθεώρηση που ίσχυε όταν εκδόθηκε το διαπιστευτήριό σας.

Μία σελίδα λίστας:

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

## Σφάλματα <!--quire:errors-->

Κάθε σφάλμα είναι έγγραφο προβλήματος 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` όταν επικοινωνείτε με την υποστήριξη.

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

Εγγραφείτε στο `/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}` από τα ακριβή byte που λάβατε, πριν αναλύσετε οποιοδήποτε 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 του Quire βρίσκεται στο `/mcp` στη διεύθυνση του οργανισμού, μέσω streamable HTTP. Ένας πελάτης MCP εντοπίζει τον διακομιστή OAuth από το `/.well-known/oauth-protected-resource`· το άτομο συνδέεται και συναινεί όπως με κάθε πελάτη OAuth. Τα εργαλεία ενεργούν ως το συγκεκριμένο άτομο, με τα δικαιώματά του, ενώ τα καταστροφικά εργαλεία ζητούν επιβεβαίωση. Οι διαχειριστές επιλέγουν ποια εργαλεία είναι διαθέσιμα στο `/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>

## Προγράμματα και API <!--quire:plans-and-the-api-->

Τα κλειδιά API, οι πελάτες OAuth, τα webhooks και ο διακομιστής MCP ανήκουν στο δικαίωμα API του προγράμματος, το οποίο περιλαμβάνεται σε κάθε τυπικό πρόγραμμα. Σε πρόγραμμα που δεν το περιλαμβάνει, απορρίπτεται η δημιουργία κλειδιού, πελάτη ή συνδρομής, οι εγγραφές REST και οι συνδέσεις MCP. Οι αναγνώσεις REST εξακολουθούν να λειτουργούν ώστε να είναι δυνατή η εξαγωγή δεδομένων. Η απόρριψη είναι έγγραφο προβλήματος με κωδικό `commerce.plan_entitlement` και κατηγορία `precondition`.

## Επεκτάσεις <!--quire:extensions-->

Οι τύποι δραστηριοτήτων, τα μπλοκ, οι μέθοδοι εγγραφής και σύνδεσης, οι τύποι ερωτήσεων, οι αναφορές, τα θέματα και οι ενσωματώσεις του ίδιου του Quire δηλώνονται μέσω του ίδιου μητρώου επεκτάσεων, στο οποίο μπορεί να προσθέσει στοιχεία μια αυτοδιαχειριζόμενη εγκατάσταση. Οι επεκτάσεις μεταγλωττίζονται μέσα στο Quire: δεν υπάρχει πρόγραμμα φόρτωσης πρόσθετων κατά την εκτέλεση και ένας φιλοξενούμενος οργανισμός δεν μπορεί να προσθέσει κάποια. Οι διαχειριστές ενεργοποιούν ή απενεργοποιούν κάθε επέκταση για τον οργανισμό τους στο `/admin/extensions` (δείτε τον [οδηγό διαχειριστή](/el/admin/extensions/)).

Για να γράψετε μία, ξεκινήστε από το δείγμα μπλοκ και θέματος στο `packages/integration/extensions/src/sample.ts`. Επιλέξτε το σημείο επέκτασης και διαβάστε το συμβόλαιό του στο `points.ts`. Έπειτα δηλώστε την επέκταση με αναγνωριστικό, έκδοση, άδεια χρήσης, όσα παρέχει και απαιτεί, καθώς και το αν μπορεί να την απενεργοποιήσει ένας οργανισμός. Καταχωρίστε την εκεί όπου συντίθενται η εφαρμογή ιστού και ο worker, ώστε να συμφωνούν. Κατά τη δημιουργία και σε κάθε κλήση του `register`, το μητρώο ελέγχει τους κανόνες κάθε σημείου, απορρίπτει ένα μη έγκυρο σύνολο κατονομάζοντας όλα τα προβλήματα και δεν αλλάζει το μητρώο. Οι δοκιμές της επέκτασης πρέπει να επαληθεύουν ότι η `extensionContractProblems` είναι κενή για αυτή και ότι η απενεργοποίησή της αλλάζει ό,τι επηρεάζει.

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