---
title: "विकासकर्ता मार्गदर्शिका"
description: "Quire REST API, OAuth, webhooks, MCP सर्भर र एक्सटेन्सनहरू।"
image: "https://docs.quirelms.com/og.png"
---

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

# विकासकर्ता मार्गदर्शिका

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

तपाईंको सङ्गठनको API ठेगाना र स्कोप भएको प्रमाण प्रयोग गर्नुहोस्। पढ्ने अनुरोधबाट सुरु गर्नुहोस्, प्रतिक्रिया जाँच्नुहोस्, र गोप्य कुरा स्रोत नियन्त्रण र दस्तावेज उदाहरणबाहिर राख्नुहोस्।

Quire को एउटा सार्वजनिक API छ: HTTPS मा REST, OpenAPI 3.1
दस्तावेजद्वारा वर्णित, घटनाका लागि हस्ताक्षरित webhooks र AI
सहायकका लागि MCP सर्भर सहित। [API सन्दर्भ](https://docs.quirelms.com/api/) ले हरेक endpoint र घटना सूचीबद्ध गर्छ।

## ठेगानाहरू <!--quire:addresses-->

हरेक सङ्गठनको आफ्नै ठेगाना हुन्छ, र API यसैअन्तर्गत रहन्छ:

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

प्रमाणले सङ्गठन निर्णय गर्छ। एउटा सङ्गठनको कुञ्जी अर्कोको ठेगानामा प्रयोग भए अस्वीकार हुन्छ।

OpenAPI दस्तावेज कुनै पनि सङ्गठनको ठेगानामा `/api/v1/openapi.json` मा दिइन्छ,
त्यसैले क्लाइन्ट जेनेरेटरले सधैँ तपाईंले कल गर्ने संस्करण देख्छन्।

## प्रमाणीकरण <!--quire:authentication-->

**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`।

<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` सत्य हुन्छ (उदाहरण
  तल)। अफसेट हुँदैन।
- **यतादेखिका परिवर्तन**: `updated_since` ले समयपछिका परिवर्तन फर्काउँछ।
  के हटाइयो जान्न यसलाई `include_deleted=true` सँग जोड्नुहोस्, वा `/<resource>/deletions` पढ्नुहोस्।
- **बाह्य पहिचायक**: धेरैजसो स्रोतले तपाईंको आफ्नै `external_id` स्वीकार्छन्,
  र `/<resource>/ext:{external_id}` ले त्यसबाट पढ्छ वा अपसर्ट गर्छ, त्यसैले सिङ्कले Quire का पहिचायक भण्डारण गर्नुपर्दैन।
- **आइडेम्पोटेन्सी**: `Idempotency-Key` हेडर `POST`, `PATCH` र
  `DELETE` मा पठाउनुहोस्। उही कुञ्जीसहित पुनः प्रयासले काम दोब्बर गर्नुको सट्टा पहिलो प्रतिक्रिया फर्काउँछ। बल्क endpoint लाई यो चाहिन्छ।
- **संस्करणहरू**: प्रमुख संस्करण पथमा छ (`/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` मा, वा
`/webhook_subscriptions` मा API मार्फत सदस्यता लिनुहोस्। घटना नामबाट (`enrolment.created`),
क्षेत्रबाट (`enrolment.*`) वा सबै (`*`) छान्नुहोस्। Quire ले पहिले `webhook.ping` पठाउँछ; तपाईंको endpoint ले जवाफ दिएपछि सदस्यता सुरु हुन्छ।

वितरणले Standard Webhooks विशिष्टता पछ्याउँछ:

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

वितरण प्रमाणित गर्न:

1. कुनै JSON पार्सिङअघि, प्राप्त ठ्याक्कै बाइटबाट `{webhook-id}.{webhook-timestamp}.{raw body}` स्ट्रिङ बनाउनुहोस्।
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-->

Quire को MCP सर्भर सङ्गठनको ठेगानामा `/mcp` मा छ,
स्ट्रिमेबल HTTP मा। MCP क्लाइन्टले `/.well-known/oauth-protected-resource` बाट OAuth सर्भर पत्ता लगाउँछ, र व्यक्ति कुनै पनि 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 का आफ्नै गतिविधि प्रकार, ब्लक, भर्ना विधि, साइन-इन विधि, प्रश्न
प्रकार, प्रतिवेदन, थिम र एकीकरण उही एक्सटेन्सन
रजिस्ट्रीबाट घोषणा गरिन्छन् जसमा स्व-होस्टेड स्थापनाले थप्न सक्छ। एक्सटेन्सन कम्पाइल हुन्छन्:
कुनै रनटाइम प्लगइन लोडर हुँदैन, र होस्ट गरिएको सङ्गठनले एउटा थप्न सक्दैन।
प्रशासकहरूले `/admin/extensions` मा आफ्नो सङ्गठनका लागि हरेक एक्सटेन्सन खोल्छन् वा बन्द गर्छन् ([प्रशासक मार्गदर्शिका](/ne/admin/extensions/) हेर्नुहोस्)।

एउटा लेख्न, `packages/integration/extensions/src/sample.ts` मा नमुना ब्लक र थिमबाट सुरु गर्नुहोस्। एक्सटेन्सन बिन्दु छान्नुहोस् र
`points.ts` मा यसको सम्झौता पढ्नुहोस्, त्यसपछि एक्सटेन्सनलाई id, संस्करण,
इजाजत, यसले के दिन्छ र माग्छ, र सङ्गठनले यसलाई बन्द गर्न सक्छ कि सक्दैन सहित घोषणा गर्नुहोस्।
वेब अनुप्रयोग र वर्कर जहाँ मिल्छन् त्यहाँ दर्ता गर्नुहोस्, ताकि दुवै
सहमत होऊन्। रजिस्ट्रीले निर्माण हुँदा र तपाईंले `register` कल गर्दा हरेक बिन्दुका आफ्नै नियम जाँच्छ र
अमान्य हुने सेटलाई हरेक समस्या नामसहित अस्वीकार गर्छ, र गर्दा रजिस्ट्री अपरिवर्तित छोड्छ। एक्सटेन्सनका आफ्नै परीक्षणले
`extensionContractProblems` यसका लागि खाली छ र यसलाई बन्द गर्दा यसले असर गर्ने कुरा परिवर्तन हुन्छ भनी दाबी गर्नुपर्छ।

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