---
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/hi/llms.txt
> Use this file to discover all available pages before exploring further.

# डेवलपर मार्गदर्शिका

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

अपने संगठन का API पता और सीमित scope वाला क्रेडेंशियल इस्तेमाल करें। पढ़ने की
रिक्वेस्ट से शुरू करें, जवाब जाँचें, और secrets को source control तथा दस्तावेज़ी
उदाहरणों से बाहर रखें।

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

क्रेडेंशियल संगठन तय करता है। एक संगठन की key दूसरे के पते पर इस्तेमाल करने पर
अस्वीकार होती है।

OpenAPI दस्तावेज़ हर संगठन के पते पर `/api/v1/openapi.json` से मिलता है, ताकि
client generator हमेशा वही संस्करण देखे जिसे आप कॉल कर रहे हैं।

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

**API keys** स्क्रिप्ट और server-to-server एकीकरण के लिए हैं। प्रशासक
`/admin/integrations/api-keys` पर एक बनाता है, उसके scopes चुनता है और उसे एक बार
देखता है। उसे bearer token के रूप में भेजें:

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

Keys `qk_live_` या `qk_test_` से शुरू होती हैं। हर एकीकरण को उसकी अपनी key दें।

**OAuth 2.1** उन ऐप्लिकेशन के लिए है जो साइन-इन व्यक्ति के रूप में काम करते हैं।
`/admin/integrations/oauth-clients` पर client रजिस्टर करें, फिर PKCE
(`/oauth/authorize`, `/oauth/token`) के साथ authorization code flow या machine
client के लिए client credentials इस्तेमाल करें। Discovery
`/.well-known/oauth-authorization-server` पर है। Scope token के काम सीमित करता
है; वह व्यक्ति की क्षमता से ज़्यादा कभी नहीं देता।

Scopes `resource:read`, `resource:write` और `resource:delete` हैं, उदाहरण के लिए
`courses:read` या `enrolments:write`। चार privileged हैं और consent screen पर
चेतावनी के साथ दिखते हैं: `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-->

- **पृष्ठांकन**: हर सूची cursor से पृष्ठांकित है। `limit` भेजें, फिर `next_cursor`
  (जो `page` में मिलता है) को `cursor` के रूप में भेजें जब तक `has_more` सही हो (उदाहरण नीचे)।
  कोई offset नहीं है।
- **इसके बाद के बदलाव**: `updated_since` किसी समय के बाद बदली चीज़ें लौटाता है।
  हटाई गई चीज़ जानने के लिए इसे `include_deleted=true` के साथ लें या
  `/<resource>/deletions` पढ़ें।
- **बाहरी पहचानकर्ता**: ज़्यादातर resources आपका `external_id` स्वीकार करते हैं;
  `/<resource>/ext:{external_id}` उसे पढ़ता या upsert करता है, इसलिए sync को Quire
  के identifiers सहेजने की ज़रूरत नहीं।
- **Idempotency**: `Idempotency-Key` header को `POST`, `PATCH` और `DELETE` के साथ भेजें।
  उसी key का retry पहला जवाब लौटाता है, काम दोबारा नहीं करता। Bulk endpoints को
  यह चाहिए।
- **संस्करण**: मुख्य संस्करण पथ में है (`/v1`)। इसके भीतर हर breaking change
  तारीख़ वाला revision है, जिसे `Quire-Version` header चुनता है, जैसे
  `Quire-Version: 2026-09-20`। Header न हो तो क्रेडेंशियल जारी होने के समय वाला
  revision मिलता है।

सूची का एक पृष्ठ:

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

## त्रुटियाँ <!--quire:errors-->

हर त्रुटि RFC 9457 problem दस्तावेज़ है:

```
{"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` लोगों के लिए लिखा है, उन्हें दिखाना
सुरक्षित है और बदल सकता है। अपरिचित code हो तो `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` के ज़रिए subscribe करें।
नाम (`enrolment.created`), पूरे क्षेत्र (`enrolment.*`) या सब (`*`) से इवेंट चुनें।
पहले Quire `webhook.ping` भेजता है; आपका endpoint जवाब दे तब subscription शुरू होती है।

डिलीवरी Standard Webhooks specification का पालन करती हैं:

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

डिलीवरी सत्यापित करने के लिए:

1. JSON पार्स करने से पहले, प्राप्त ठीक bytes से `{webhook-id}.{webhook-timestamp}.{raw body}`
   string बनाएँ।
2. Subscription secret से उस पर HMAC-SHA256 निकालकर base64 करें।
3. हर `v1,` मान की `webhook-signature` में constant time से तुलना करें। Secret
   बदलने के दौरान दो मान हो सकते हैं; किसी एक का मिलना मान्य है।
4. अपनी घड़ी से पाँच मिनट से अधिक अंतर वाला timestamp अस्वीकार करें।

```
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` पर duplicate रोकें: डिलीवरी एक से ज़्यादा बार आ सकती है। body में
पहचानकर्ता और छोटा सारांश होता है; मौजूदा स्थिति के लिए resource लाएँ। विफल
डिलीवरी 72 घंटे तक बढ़ते अंतराल पर फिर भेजी जाती हैं और delivery log से replay
की जा सकती हैं।

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

Quire का MCP सर्वर संगठन के पते पर `/mcp` में streamable HTTP के ज़रिए है। MCP
client OAuth सर्वर को `/.well-known/oauth-protected-resource` से खोजता है; व्यक्ति
किसी भी OAuth client की तरह साइन इन करके सहमति देता है। Tools उस व्यक्ति की
अनुमतियों के साथ उसी के रूप में काम करते हैं और नुकसानदेह tools पुष्टि माँगते हैं।
प्रशासक `/admin/integrations/mcp` पर उपलब्ध tools चुनते हैं।

<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 keys, OAuth clients, webhooks और MCP सर्वर योजना के API entitlement में आते
हैं, जो हर standard योजना में है। यह न हो तो key, client या subscription बनाने से
मना किया जाता है, REST writes और MCP connections अस्वीकार होते हैं, और डेटा
निर्यात योग्य रहे इसलिए REST reads चलते रहते हैं। इनकार `commerce.plan_entitlement`
code वाले problem दस्तावेज़ में आता है, जिसकी श्रेणी `precondition` है।

## एक्सटेंशन <!--quire:extensions-->

Quire के गतिविधि प्रकार, blocks, नामांकन तरीके, साइन-इन तरीके, प्रश्न प्रकार,
रिपोर्ट, थीम और एकीकरण उसी extension registry से घोषित होते हैं जिसमें अपने सर्वर
पर चलने वाला इंस्टॉलेशन जोड़ सकता है। एक्सटेंशन compile होकर आते हैं: runtime
plugin loader नहीं है और होस्टेड संगठन उन्हें जोड़ नहीं सकता। प्रशासक
`/admin/extensions` पर संगठन के लिए हर एक्सटेंशन चालू या बंद करते हैं (देखें
[प्रशासक मार्गदर्शिका](/hi/admin/extensions/))।

एक लिखने के लिए `packages/integration/extensions/src/sample.ts` में sample block
और theme से शुरू करें। Extension point चुनें और `points.ts` में उसका अनुबंध पढ़ें,
फिर extension को id, version, licence, वह क्या देता और माँगता है, और संगठन उसे
बंद कर सकता है या नहीं—इनके साथ घोषित करें। जहाँ web app और worker संयोजित होते
हैं वहाँ उसे रजिस्टर करें ताकि दोनों सहमत हों। Registry बनते समय और हर `register`
कॉल पर हर point के अपने नियम जाँचती है; अमान्य समूह को सभी समस्याएँ बताकर
अस्वीकार करती है और registry अपरिवर्तित छोड़ती है। Extension के अपने tests को
जाँचना चाहिए कि `extensionContractProblems` उसके लिए खाली है और उसे बंद करने से
प्रभावित चीज़ बदलती है।

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