HTTP पर Sellio को इंटीग्रेट करें या अपने AI एजेंट को जोड़ें
एक सरल REST API और एक नेटिव MCP सर्वर, वही key, वही tenant scope और वही rate limit के साथ। किसी भी object के fields खोजें और मिनटों में records पढ़ना और लिखना शुरू करें।
क्विकस्टार्ट
तीन क़दमों में शून्य से अपनी पहली कॉल तक:
- CRM में, Settings → API & developers खोलें और एक API key जनरेट करें। इसे सुरक्षित रखें; यह दोबारा नहीं दिखाई जाती।
- key को Authorization: Bearer header में उपयोग करें। यह स्वामी tenant की पहचान करती है, इसलिए सब कुछ पहले से उसी के दायरे में है।
- अपनी पहली कॉल करें और अपने objects की सूची पाएँ।
curl -H "Authorization: Bearer sk_live_..." \
https://www.selliocrm.com/api/v1/objectsप्रमाणीकरण
हर request एक API key को Authorization: Bearer header में ले जाती है। वह key स्वामी tenant की पहचान करती है, इसलिए सब कुछ स्वतः उसी के दायरे में होता है, RLS और RBAC के साथ। key को कभी ब्राउज़र में उजागर न करें; इसे केवल server-side उपयोग करें। आप keys को Settings → API & developers में जनरेट और रद्द करते हैं।
Key के दायरे
जब आप एक key जनरेट करते हैं तो आप उसका दायरा चुनते हैं और हर integration को केवल उतनी ही पहुँच देते हैं जितनी उसे चाहिए। सीमाएं REST और MCP में एक ही तरह लागू होती हैं, क्योंकि दोनों सतहें वही key और वही नियंत्रण उपयोग करती हैं। बिना किसी दायरे वाली key (डिफ़ॉल्ट) को सभी objects पर पूरी read और write पहुँच होती है, पहले की तरह।
- केवल पढ़ें: key डेटा पढ़ती है पर बना, संपादित या हटा नहीं सकती। यह REST में POST, PATCH और DELETE और MCP में create_record, update_record और delete_record tools को रोकती है, 403 और { "error": "errors.apiKeyReadOnly" } के साथ।
- objects तक सीमित: वे objects चुनें जिन्हें key पहुँच सकती है। सूची के बाहर कोई भी object 403 लौटाता है { "error": "errors.apiKeyObjectDenied" } के साथ। object की सूची पहले से दायरे के अनुसार फ़िल्टर होकर आती है, और activities को activity object के रूप में गिना जाता है।
- हटाने की अनुमति दें: डिफ़ॉल्ट रूप से एक key कभी नहीं हटाती (write सक्षम होने पर भी नहीं)। DELETE /{object}/{id} और delete_record tool को सक्षम करने के लिए key जनरेट करते समय इसे चालू करें। इसके बिना, हटाना 403 लौटाता है { "error": "errors.apiKeyDeleteDenied" } के साथ। हटाना सॉफ़्ट है: records ट्रैश में जाते हैं और पुनर्स्थापित किए जा सकते हैं।
REST API v1
किसी भी object के records, JSON भेजते और प्राप्त करते हुए। {object} apiName है (उदाहरण के लिए contact, lead, opportunity) और {id} record का uuid है। कस्टम objects वही जेनेरिक endpoints उपयोग करते हैं।
सूची पैरामीटर (GET /{object}): limit (1 से 500, डिफ़ॉल्ट 50), offset (pagination offset, डिफ़ॉल्ट 0; total, total फ़ील्ड में है), search (नाम से खोज, accent और case insensitive), order (:asc या :desc के साथ field) और filter। समृद्ध filters: कई को जोड़ने के लिए filter=field:operator:value दोहराएँ (उदा. filter=amount:gte:1000&filter=stage:eq:won)। ऑपरेटर: eq, neq, contains, gt, lt, gte, lte, empty, not_empty (empty और not_empty कोई value नहीं लेते)। Filters लॉजिकल AND से जुड़ते हैं (कोई OR नहीं) और प्रति request 12 तक। पुराना रूप filter=field:value (बिना ऑपरेटर) अब भी ठीक समानता का अर्थ रखता है।
# सूची (limit, offset, search, filter, order)
curl -H "Authorization: Bearer sk_live_..." \
"https://www.selliocrm.com/api/v1/opportunity?limit=20&order=updated_at:desc&filter=stage:won"
# समृद्ध filters: filter=field:operator:value दोहराएँ (उनके बीच AND)
curl -H "Authorization: Bearer sk_live_..." \
"https://www.selliocrm.com/api/v1/opportunity?filter=amount:gte:1000&filter=stage:eq:won&filter=name:contains:acme"
# एक record
curl -H "Authorization: Bearer sk_live_..." \
https://www.selliocrm.com/api/v1/contact/8f3c...
# बनाएँ
curl -X POST -H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"Ana Souza","email":"ana@acme.com","source":"site"}' \
https://www.selliocrm.com/api/v1/contact
# थोक में बनाएँ (500 तक; प्रति आइटम आंशिक सफलता वाली response)
curl -X POST -H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"records":[{"name":"Ana"},{"name":"Bruno"}]}' \
https://www.selliocrm.com/api/v1/contact/bulk
# → { "results": [ { "index": 0, "ok": true, "id": "..." },
# { "index": 1, "ok": false, "error": "..." } ],
# "created": 1, "failed": 1 }
# अपडेट (आंशिक)
curl -X PATCH -H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"source":"referral"}' \
https://www.selliocrm.com/api/v1/contact/8f3c...
# हटाएँ (सॉफ़्ट, ट्रैश में जाता है; key पर delete दायरा आवश्यक)
curl -X DELETE -H "Authorization: Bearer sk_live_..." \
https://www.selliocrm.com/api/v1/contact/8f3c...Object और field डिस्कवरी
record बनाने या अपडेट करने से पहले, object fields खोजें: क्या मौजूद है, क्या आवश्यक है और एक select कौन-से values स्वीकार करता है। कोई अनुमान नहीं, और किसी मौजूदा record का निरीक्षण करने की ज़रूरत नहीं। GET /objects/{apiName} object और उसके fields लौटाता है, required, options (select के लिए), targetObject (lookup के लिए), unique और readOnly (formula या rollup fields, जो लिखने योग्य नहीं) के साथ।
GET https://www.selliocrm.com/api/v1/objects/contact
# → {
# "apiName": "contact",
# "label": "Contact",
# "fields": [
# { "apiName": "name", "label": "Name", "type": "text", "required": true },
# { "apiName": "email", "label": "Email", "type": "email", "required": false },
# { "apiName": "source", "label": "Source", "type": "select", "required": true,
# "options": [ { "value": "site", "label": "Website" },
# { "value": "referral", "label": "Referral" } ] },
# { "apiName": "company", "label": "Company", "type": "lookup",
# "required": false, "targetObject": "company" }
# ]
# }MCP में, describe_object tool एजेंट को वही fields लौटाता है।
BI और automation के लिए डेटा
GET /data/{object} records को स्थिर सारणीबद्ध पंक्तियों में समतल करके लौटाता है (निश्चित columns id, created_at, updated_at, owner_id, साथ में प्रति field एक), updated_at desc से क्रमबद्ध। यह page और pageSize (या limit और offset) द्वारा pagination, इंक्रीमेंटल filters updated_since और created_since (ISO 8601), और filter=field:value स्वीकार करता है। Power BI, Tableau, Looker और Zapier, Make तथा n8n से polling के लिए बनाया गया।
curl -H "Authorization: Bearer sk_live_..." \
"https://www.selliocrm.com/api/v1/data/opportunity?pageSize=100&updated_since=2026-01-01T00:00:00Z"
# → { "object": "opportunity",
# "columns": [ { "name": "id", "type": "id" }, ... ],
# "page": 1, "pageSize": 100, "total": 42,
# "rows": [ { "id": "...", "created_at": "...", "amount": 1200, ... } ] }AI एजेंट के लिए MCP सर्वर
Sellio exposes a native MCP (Model Context Protocol) server so your AI agent can read and write the CRM safely. It is the same API key, the same rate limit, the same validations and the same RBAC. The server URL is https://www.selliocrm.com/api/mcp. Available tools:
list_objects: tenant objects की सूची पाएँ।describe_object: एक object के fields (required, types, options)।list_records: records की सूची पाएँ और खोजें।get_record: id द्वारा एक record।create_record: एक record बनाएँ।update_record: fields अपडेट करें।delete_record: हटाएँ (सॉफ़्ट → ट्रैश)। key पर delete दायरा आवश्यक।
जो clients HTTP पर remote MCP का समर्थन करते हैं, वे URL को Authorization: Bearer header के साथ उपयोग करते हैं। नेटिव remote HTTP के बिना clients पर, mcp-remote bridge उपयोग करें:
{
"mcpServers": {
"sellio-crm": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://www.selliocrm.com/api/mcp",
"--header", "Authorization: Bearer sk_live_..."
]
}
}
}OAuth और कनेक्टेड ऐप्स
उपयोगकर्ता की ओर से इंटीग्रेट करने के लिए (बिना ग्राहक के एक admin key चिपकाए), PKCE के साथ OAuth 2.0 Authorization Code flow उपयोग करें। उपयोगकर्ता अनुरोधित scopes के साथ एक consent स्क्रीन देखता है, स्वीकृति देता है, और आपके ऐप को एक access token मिलता है जो केवल वही कर सकता है जिसकी सहमति दी गई। ऐप्स क्यूरेटेड हैं: client_id और client_secret पाने के लिए ऐप को marketplace में पंजीकृत और प्रकाशित करें। यह flow चार क़दमों में:
- उपयोगकर्ता को /api/oauth/authorize पर रीडायरेक्ट करें, client_id, redirect_uri (ऐप allowlist के विरुद्ध ठीक मिलान), scope, state और PKCE (code_challenge_method=S256 के साथ code_challenge) के साथ। PKCE आवश्यक है।
- लॉग-इन उपयोगकर्ता consent स्क्रीन देखता है और स्वीकृति देता है। CRM आपके redirect_uri पर code और वही state के साथ वापस रीडायरेक्ट करता है।
- अपने सर्वर पर, POST /api/oauth/token पर code का आदान-प्रदान करें (code_verifier, client_id, client_secret और redirect_uri के साथ) एक access token (Bearer, लगभग 1 घंटा) और एक refresh token के लिए।
- REST v1 API और MCP सर्वर को Authorization: Bearer at_... के साथ कॉल करें, consent के दायरे में। grant_type=refresh_token के साथ नवीनीकृत करें; refresh घुमाया जाता है (पुराना उपयोग पर समाप्त हो जाता है) और पुनः उपयोग token परिवार को रद्द कर देता है।
# 1) उपयोगकर्ता को consent पर भेजें (PKCE S256 + state)
GET https://www.selliocrm.com/api/oauth/authorize
?response_type=code
&client_id=app_...
&redirect_uri=https://your-app.example.com/callback # allowlist से ठीक मिलान
&scope=records:read%20records:write:opportunity%20activities:read
&state=<random>
&code_challenge=<base64url(sha256(code_verifier))>
&code_challenge_method=S256
# → उपयोगकर्ता स्वीकृति देता है → 302 redirect_uri?code=<authcode>&state=<...>
# 2) code को tokens के लिए बदलें (server-side; client_secret भेजें)
curl -X POST https://www.selliocrm.com/api/oauth/token \
-d grant_type=authorization_code \
-d code=<authcode> \
-d code_verifier=<code_verifier> \
-d client_id=app_... \
-d client_secret=secret_... \
-d redirect_uri=https://your-app.example.com/callback
# → { "access_token": "at_...", "token_type": "Bearer",
# "expires_in": 3600, "refresh_token": "rt_...",
# "scope": "records:read records:write:opportunity activities:read" }
# 3) access token के साथ v1 / MCP API कॉल करें (consent के दायरे में)
curl -H "Authorization: Bearer at_..." https://www.selliocrm.com/api/v1/contact
# 4) refresh token के साथ नवीनीकृत करें (घुमाया गया: पुराना rt_ उपयोग पर समाप्त)
curl -X POST https://www.selliocrm.com/api/oauth/token \
-d grant_type=refresh_token -d refresh_token=rt_... \
-d client_id=app_... -d client_secret=secret_...OAuth scopes keys के समान प्रवर्तन से मैप होते हैं (read, write और प्रति object)। न्यूनतम आवश्यक का अनुरोध करें; उपयोगकर्ता इंस्टॉल पर एक उपसमूह प्रदान करता है और token केवल उसी के भीतर काम करता है।
- records:read और records:write: सभी objects के records पढ़ना और लिखना (मोटा)।
- records:read:contact और records:write:opportunity: प्रति-object शोधन (apiName), जब ऐप को केवल कुछ objects चाहिए।
- activities:read और activities:write: activities पढ़ना और लिखना।
- objects:read: objects और fields की संरचना खोजें।
एम्बेडेड विजेट
आपका ऐप CRM के अंदर अपनी ख़ुद की स्क्रीन (एक widget) एम्बेड कर सकता है: एक record के विवरण पर या dashboard पर। widget एक sandboxed iframe में चलता है, जो आपके अपने origin से सर्व होता है (ऐप allowlist पर)। host widget को postMessage पर केवल UI context भेजता है: recordId, objectApiName, locale और theme। उस संदेश में कोई व्यावसायिक डेटा, token या secret नहीं जाता। डेटा पढ़ने या लिखने के लिए, आपका widget अपने ख़ुद के token के साथ OAuth API उपयोग करता है (वे scopes जो tenant ने इंस्टॉल पर दिए)।
- अपने ऐप में widget घोषित करें (key, title, location record या dashboard और embedUrl) और embedUrl origin को ऐप origin allowlist पर सूचीबद्ध करें।
- अपने widget में, host संदेशों को सुनें और केवल host origin (event.origin) से आने वालों को स्वीकार करें। host sellio:widget:context (version 1) भेजता है { recordId, objectApiName, locale, theme, installId } के साथ।
- आपका widget केवल sellio:widget:ready (context दोबारा प्राप्त करने के लिए) और sellio:widget:resize को { height } के साथ (अपनी ऊँचाई फ़िट करने के लिए, सीमित) वापस भेज सकता है। कोई अन्य संदेश अनदेखा किया जाता है।
- डेटा के लिए, ऐप token के साथ OAuth API (Bearer) कॉल करें। host कभी postMessage पर token या डेटा नहीं सौंपता।
// आपके widget के अंदर (iframe में चलने वाला पेज https://widgets.yourapp.com)।
// host केवल UI context भेजता है। डेटा के लिए, अपने token के साथ OAuth API उपयोग करें।
const HOST = 'https://www.selliocrm.com'; // हमेशा host origin सत्यापित करें
window.addEventListener('message', (event) => {
if (event.origin !== HOST) return; // केवल host origin स्वीकार करें
const msg = event.data;
if (!msg || msg.version !== 1) return;
if (msg.type === 'sellio:widget:context') {
const { recordId, objectApiName, locale, theme, installId } = msg.payload;
render(recordId, objectApiName, locale, theme);
// अपने OAuth token के साथ डेटा प्राप्त करें (कभी postMessage से नहीं आता):
// fetch(HOST + '/api/v1/' + objectApiName + '/' + recordId,
// { headers: { Authorization: 'Bearer ' + accessToken } })
}
});
// लोड पर context का अनुरोध करें और ऊँचाई को अपनी सामग्री के अनुसार समायोजित करें:
parent.postMessage({ type: 'sellio:widget:ready', version: 1 }, HOST);
parent.postMessage({ type: 'sellio:widget:resize', version: 1,
payload: { height: document.body.scrollHeight } }, HOST);सुरक्षा: iframe sandboxed और cross-origin है, इसलिए widget host के DOM या cookies तक नहीं पहुँच सकता। host हर postMessage (आने और जाने) पर ठीक origin सत्यापित करता है और embedUrl हमेशा ऐप allowlist के विरुद्ध जाँचा जाता है। widgets लगाने के लिए widgets:embed scope का अनुरोध करें।
आउटबाउंड webhooks
CRM events को रीयल टाइम में प्राप्त करें। Settings में एक गंतव्य URL पंजीकृत करें और वे events चुनें जिनकी आप सदस्यता लेते हैं। हर डिलीवरी एक JSON body वाला POST है, event के नाम के साथ x-sellio-event header, और body के HMAC-SHA256 हस्ताक्षर के साथ x-sellio-signature header। secret (whsec_...) तब दिखाया जाता है जब आप webhook बनाते हैं।
Event कैटलॉग
उदाहरण payload
POST https://your-server.example.com/webhook
x-sellio-event: record.created
x-sellio-signature: sha256=<hmac-hex>
Content-Type: application/json
{
"event": "record.created",
"tenantId": "…",
"objectApiName": "lead",
"recordId": "8f3c…",
"data": { "name": "Ana Souza", "email": "ana@acme.com" },
"timestamp": "2026-07-23T12:00:00.000Z"
}Campaign और flow events (flow.*) अतिरिक्त enrollment fields ले जाते हैं:
{
"event": "flow.replied",
"tenantId": "…",
"flowId": "…",
"flowName": "Outbound Q3",
"recordId": "8f3c…",
"enrollmentId": "…",
"objectApiName": "lead",
"data": { "name": "Ana Souza", "email": "ana@acme.com" },
"meta": {},
"timestamp": "2026-07-23T12:00:00.000Z"
}हस्ताक्षर कैसे सत्यापित करें
अपने whsec_... secret का उपयोग करते हुए RAW body (जैसा प्राप्त हुआ बिल्कुल वैसा, बिना दोबारा serialize किए) का HMAC-SHA256 गणना करें, sha256=<hex> रूप में, और उसे x-sellio-signature header के विरुद्ध constant time में तुलना करें। मेल न होने पर अस्वीकार करें।
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody = ठीक प्राप्त body (string), बिना दोबारा serialize किए।
function isValid(rawBody, signatureHeader, secret) {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(signatureHeader || '');
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}
// Express: raw body पाने के लिए express.raw({ type: 'application/json' }) उपयोग करें।
app.post('/webhook', (req, res) => {
const ok = isValid(req.body.toString('utf8'), req.header('x-sellio-signature'), process.env.SELLIO_WHSEC);
if (!ok) return res.status(401).end();
const event = req.header('x-sellio-event');
// ... event को प्रोसेस करें
res.status(200).end();
});Rate limit
हर key की प्रति-मिनट सीमा होती है (डिफ़ॉल्ट 120, कॉन्फ़िगर करने योग्य)। Responses में X-RateLimit-Limit, X-RateLimit-Remaining और X-RateLimit-Reset headers शामिल होते हैं। अधिकता पर, API 429 लौटाता है Retry-After header के साथ।
त्रुटि प्रारूप
त्रुटियाँ JSON को { "error": "message" } रूप में मिलती HTTP स्थिति के साथ लौटाती हैं:
{ "error": "required field: source" } # HTTP 400- 200 और 201: सफलता (create पर 201)।
- 400: सत्यापन या व्यावसायिक नियम।
- 401: अनुपस्थित या अमान्य key।
- 403: object के लिए कोई अनुमति नहीं (RBAC), या key दायरे द्वारा अवरुद्ध (केवल पढ़ें, दायरे के बाहर object, या हटाना सक्षम नहीं)।
- 404: object या record नहीं मिला (अस्तित्वहीन id के DELETE/PATCH सहित)।
- 429: rate limit पार (Retry-After header देखें)।
ज्ञात सीमाएं
- Filters लॉजिकल AND से जुड़ते हैं (सब एक साथ सत्य); filters के बीच कोई OR नहीं है।
- अपडेट आंशिक हैं (PATCH): आप केवल बदलने वाले fields भेजते हैं। पूरे record प्रतिस्थापन के लिए कोई PUT नहीं है।
विनिर्देश और collection
OpenAPI 3.1 विनिर्देश को Swagger, Insomnia या Postman में इंपोर्ट करें, या हर endpoint और apiKey तथा baseUrl variables के साथ तैयार Postman collection डाउनलोड करें।