SPINE Developer API
Xarici layihələr üçün vahid platforma API-si: poçt, SSL sertifikatları, DNS, poçt qutuları, domenlər, webhook-lar və Telegram botları, hamısı tək açarla.
BASE ·https://api.spine.maxsystems.az
🔑 Autentifikasiya
Hər sorğuda Authorization: Bearer spine_sk_… başlığı. Açar konsolda verilir, bir dəfə göstərilir və bir kliklə ləğv olunur.
⚙️ Uçot və limitlər
Hər açar sorğuları sayır; defolt limit 120/dəq (tənzimlənir). Aşılma zamanı 429. Günlük/aylıq kvotalar istəyə görədir.
⚠️ Xəta kodları
401 yanlış açar · 403 icazə yoxdur · 429 limit · 400 yanlış sorğu (error sahəsi).
| Scope | Nəyə icazə verir |
|---|---|
mail:send | Məktub göndərmə |
mail:read | Öz qutularınızın məktublarını oxumaq |
mail:mailboxes | Qutuların yaradılması və idarəsi |
mail:domains | Domenlərin qoşulması və statusu |
cert:issue | Sertifikatların sifarişi və yenidən buraxılışı |
cert:read | Sertifikatların statusu və yüklənməsi |
dns:read | Zonanın DNS yazılarının oxunması |
dns:records | Zonanın DNS yazılarının idarəsi |
webhooks | Webhook-lara abunə (gələn məktublar, çatdırılma hadisələri) |
telegram:bots | Layihənin Telegram botlarının idarəsi |
webmail:login | İşçinin webmail-a avto-giriş linkləri (yerləşdirmə üçün SSO) |
Poçt
/v1/mail/sendmail:sendMəktub göndər. Göndərənin domeni SPINE poçtuna qoşulmalı və layihəyə aid olmalıdır.
from | göndərənin ünvanı (məcburidir) |
to | alan (məcburidir) |
subject | mövzu (və ya template) |
text / html | məktubun mətni |
category | statistika üçün etiket (məcburi deyil) |
idempotencyKey | dublikatdan qoruma (məcburi deyil) |
{
"from": "noreply@ваш-домен",
"to": "user@example.com",
"subject": "Привет",
"text": "Тело письма"
}{ "id": "01K…", "status": "sent", "relayMessageId": "…" }
curl -X POST "https://api.spine.maxsystems.az/v1/mail/send" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"noreply@ваш-домен","to":"user@example.com","subject":"Привет","text":"Тело письма"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/mail/send", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
"from": "noreply@ваш-домен",
"to": "user@example.com",
"subject": "Привет",
"text": "Тело письма"
})
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/mail/send",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"from":"noreply@ваш-домен","to":"user@example.com","subject":"Привет","text":"Тело письма"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mail/send");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"from":"noreply@ваш-домен","to":"user@example.com","subject":"Привет","text":"Тело письма"}',
]);
$data = json_decode(curl_exec($ch), true);
Sertifikatlar
/v1/certs/issuecert:issueİdarə olunan zonadakı domen üçün SSL sertifikatı sifariş et. Buraxılış ~15–30 san.
domains | domenlərin siyahısı, wildcard *.domain olar (məcburidir) |
csr | öz CSR-iniz, onda şəxsi açar sizdə qalır (məcburi deyil) |
autoRenew | avto-yeniləmə, defolt olaraq true |
{ "domains": ["app.ваш-домен", "*.ваш-домен"], "autoRenew": true }{ "id": "…", "subject": "app.ваш-домен", "sans": [...], "status": "pending" }
curl -X POST "https://api.spine.maxsystems.az/v1/certs/issue" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"domains":["app.ваш-домен","*.ваш-домен"],"autoRenew":true}'
const res = await fetch("https://api.spine.maxsystems.az/v1/certs/issue", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "domains": ["app.ваш-домен", "*.ваш-домен"], "autoRenew": true })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/certs/issue",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"domains":["app.ваш-домен","*.ваш-домен"],"autoRenew":true}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/certs/issue");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"domains":["app.ваш-домен","*.ваш-домен"],"autoRenew":true}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/certs/{id}/statuscert:readSertifikatın statusu (pending → active | failed).
{ "status": "active", "notAfter": "…", "daysLeft": 89 }
curl -X GET "https://api.spine.maxsystems.az/v1/certs/{id}/status" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/certs/{id}/status", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/certs/{id}/status",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/certs/{id}/status");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/certs/{id}/downloadcert:readSertifikatı yüklə (fullchain + şəxsi açar; CSR ilə buraxılan sertifikatlar üçün privkey=null).
{ "fullchain": "-----BEGIN CERTIFICATE-----…", "privkey": "…" }
curl -X GET "https://api.spine.maxsystems.az/v1/certs/{id}/download" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/certs/{id}/download", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/certs/{id}/download",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/certs/{id}/download");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
Poçt qutuları
/v1/mailboxesmail:mailboxesÖz domenində poçt qutusu yarat.
name | @ işarəsindən əvvəlki qutu adı (2–40, [a-z0-9._-]) |
domain | layihə domeni (məcburidir) |
password | qutu parolu (min. 8) |
description | təsvir (məcburi deyil) |
{ "name": "info", "domain": "ваш-домен", "password": "…" }{ "email": "info@ваш-домен", "id": "…" }
curl -X POST "https://api.spine.maxsystems.az/v1/mailboxes" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"info","domain":"ваш-домен","password":"…"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/mailboxes", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "name": "info", "domain": "ваш-домен", "password": "…" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/mailboxes",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"name":"info","domain":"ваш-домен","password":"…"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mailboxes");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"name":"info","domain":"ваш-домен","password":"…"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/mailboxesmail:mailboxesLayihə domenlərindəki poçt qutuları və qrupların siyahısı. type sahəsi: personal (şəxsi), shared (ortaq, bir neçə nəfərin girişi var), group (paylama qrupu). Qruplarda membersCount sahəsi olur.
{ "mailboxes": [ { "id": "…", "email": "ivan@ваш-домен", "type": "personal", "usedBytes": 0 }, { "id": "…", "email": "team@ваш-домен", "type": "group", "membersCount": 4 } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/mailboxes" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/mailboxes", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/mailboxes",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mailboxes");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/mailboxes/{id}mail:mailboxesPoçt qutusunu sil (yalnız öz domenində).
{ "deleted": true }
curl -X DELETE "https://api.spine.maxsystems.az/v1/mailboxes/{id}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/mailboxes/{id}", {
method: "DELETE",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.delete(
"https://api.spine.maxsystems.az/v1/mailboxes/{id}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mailboxes/{id}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/mailboxes/{id}/messagesmail:readQutudakı son məktubların siyahısı (təzələr yuxarıda). Ünvana görə süzgəcləmək olar, kontaktla yazışma paneli üçün əlverişlidir.
limit | neçə məktub qaytarılsın, 100-ə qədər (defolt 20) |
with | kontaktın ünvanı: ondan və ya ona olan məktublar (qarşı tərəflə yazışma) |
from | göndərənə görə süzgəc (ünvanın alt sətri) |
to | alana görə süzgəc (ünvanın alt sətri) |
{ "messages": [ { "id": "eaaaaab", "messageId": ["<abc@bank.az>"], "subject": "…", "from": [{"email":"…"}], "receivedAt": "…", "preview": "…" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/mailboxes/{id}/messages/{msgId}mail:readTam məktub: mətn, RFC Message-ID/In-Reply-To/References (thread üçün) və xam başlıqlar. Diqqət: yoldakı id per-mailbox-dır (qlobal deyil); qlobal açar messageId-dir.
{ "id": "eaaaaab", "messageId": "<abc@bank.az>", "inReplyTo": ["<prev@you.az>"], "references": ["<root@…>"], "subject": "…", "from": […], "to": […], "receivedAt": "…", "text": "тело письма", "headers": [{"name":"Message-ID","value":"<abc@bank.az>"}, …] }
curl -X GET "https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages/{msgId}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages/{msgId}", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages/{msgId}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/mailboxes/{id}/messages/{msgId}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
Qruplar
/v1/groupsmail:mailboxesLayihənin paylama qruplarının siyahısı. Qrup, team@domain ünvanıdır; ona gələn məktub bütün üzvlərin şəxsi qutularına paylanır.
{ "groups": [ { "id": "…", "email": "team@ваш-домен", "membersCount": 4 } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/groups" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/groups", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/groups",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/groupsmail:mailboxesname@domain paylama qrupu yarat. Domen sizin layihənizə aid olmalıdır.
domain | layihə domeni (məcburidir) |
name | ünvan adı, 2-40 simvol [a-z0-9._-] (məcburidir) |
description | qrupun təsviri (məcburi deyil) |
{ "domain": "ваш-домен.az", "name": "team", "description": "Вся команда" }{ "id": "…", "email": "team@ваш-домен.az" }
curl -X POST "https://api.spine.maxsystems.az/v1/groups" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"ваш-домен.az","name":"team","description":"Вся команда"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/groups", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "domain": "ваш-домен.az", "name": "team", "description": "Вся команда" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/groups",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"domain":"ваш-домен.az","name":"team","description":"Вся команда"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"domain":"ваш-домен.az","name":"team","description":"Вся команда"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/groups/{id}mail:mailboxesQrupu sil.
{ "deleted": true }
curl -X DELETE "https://api.spine.maxsystems.az/v1/groups/{id}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/groups/{id}", {
method: "DELETE",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.delete(
"https://api.spine.maxsystems.az/v1/groups/{id}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups/{id}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/groups/{id}/membersmail:mailboxesQrupun üzvləri (məktubun paylandığı qutular).
{ "members": [ { "id": "…", "email": "ivan@ваш-домен.az" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/groups/{id}/members" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/groups/{id}/members", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/groups/{id}/members",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups/{id}/members");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/groups/{id}/membersmail:mailboxesPoçt qutusunu ünvanına görə qrupa əlavə et.
{ "mailbox": "ivan@ваш-домен.az" }{ "ok": true, "member": { "id": "…", "email": "ivan@ваш-домен.az" } }
curl -X POST "https://api.spine.maxsystems.az/v1/groups/{id}/members" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"mailbox":"ivan@ваш-домен.az"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/groups/{id}/members", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "mailbox": "ivan@ваш-домен.az" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/groups/{id}/members",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"mailbox":"ivan@ваш-домен.az"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups/{id}/members");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"mailbox":"ivan@ваш-домен.az"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/groups/{id}/members/{userId}mail:mailboxesÜzvü qrupdan çıxar.
{ "ok": true }
curl -X DELETE "https://api.spine.maxsystems.az/v1/groups/{id}/members/{userId}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/groups/{id}/members/{userId}", {
method: "DELETE",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.delete(
"https://api.spine.maxsystems.az/v1/groups/{id}/members/{userId}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/groups/{id}/members/{userId}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
Webmail (SSO)
/v1/webmail/login-linkwebmail:loginİşçiyə ÖZ webmail qutusuna birdəfəlik avto-giriş linki ver, beləcə poçtu tətbiqinizə (məs. CRM) yerləşdirə bilərsiniz. Link 60 saniyə yaşayır və birdəfəlikdir: onu açanda (yeni tabda və ya iframe-də) işçi ikinci girişsiz poçta düşür. Qutu sizin domendə olmalıdır.
mailbox | işçinin sizin domendəki tam qutu ünvanı (məcburidir) |
{ "mailbox": "ivan@ваш-домен.az" }{ "url": "https://webmail.ваш-домен.az/?login_token=…", "email": "ivan@ваш-домен.az", "expiresIn": 60 }
curl -X POST "https://api.spine.maxsystems.az/v1/webmail/login-link" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"mailbox":"ivan@ваш-домен.az"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/webmail/login-link", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "mailbox": "ivan@ваш-домен.az" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/webmail/login-link",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"mailbox":"ivan@ваш-домен.az"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webmail/login-link");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"mailbox":"ivan@ваш-домен.az"}',
]);
$data = json_decode(curl_exec($ch), true);
Domenlər
/v1/maildomainsmail:domainsDomeni poçta qoş (domeni yaradır və mümkün olduqda DNS-i özü dərc edir).
{ "name": "ваш-домен" }{ "id": "…", "name": "ваш-домен", "autoDns": { "created": 6 }, "records": [...], "ready": false }
curl -X POST "https://api.spine.maxsystems.az/v1/maildomains" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"ваш-домен"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/maildomains", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "name": "ваш-домен" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/maildomains",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"name":"ваш-домен"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/maildomains");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"name":"ваш-домен"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/maildomainsmail:domainsLayihənin qoşulmuş domenlərinin siyahısı.
{ "domains": [ { "id": "…", "name": "ваш-домен" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/maildomains" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/maildomains", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/maildomains",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/maildomains");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/maildomains/{domain}mail:domainsDNS yazıları və domenin doğrulama statusu.
{ "name": "ваш-домен", "records": [...], "ready": true }
curl -X GET "https://api.spine.maxsystems.az/v1/maildomains/{domain}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/maildomains/{domain}", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/maildomains/{domain}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/maildomains/{domain}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
DNS
/v1/dns/{zone}/recordsdns:readZonanın DNS yazılarının siyahısı (zona layihəyə bağlı olmalıdır).
{ "zone": "ваш-домен", "records": [ { "id": "…", "type": "A", "name": "@", "data": "1.2.3.4" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/dns/{zone}/records" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/dns/{zone}/records", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/dns/{zone}/records",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/dns/{zone}/records");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/dns/{zone}/recordsdns:recordsLayihə zonasında DNS yazısı yarat.
type | A | AAAA | TXT | MX | CNAME | NS | SRV | CAA |
name | yazının adı (kök üçün '@') |
data | dəyər |
priority / ttl | MX / TTL üçün (məcburi deyil) |
{ "type": "CNAME", "name": "app", "data": "target.example.com" }{ "created": true }
curl -X POST "https://api.spine.maxsystems.az/v1/dns/{zone}/records" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"type":"CNAME","name":"app","data":"target.example.com"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/dns/{zone}/records", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "type": "CNAME", "name": "app", "data": "target.example.com" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/dns/{zone}/records",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"type":"CNAME","name":"app","data":"target.example.com"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/dns/{zone}/records");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"type":"CNAME","name":"app","data":"target.example.com"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/dns/{zone}/records/{id}dns:recordsDNS yazısını sil. GoDaddy üçün ?data=<dəyər> əlavə et.
{ "deleted": true }
curl -X DELETE "https://api.spine.maxsystems.az/v1/dns/{zone}/records/{id}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/dns/{zone}/records/{id}", {
method: "DELETE",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.delete(
"https://api.spine.maxsystems.az/v1/dns/{zone}/records/{id}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/dns/{zone}/records/{id}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
Webhook-lar
/v1/webhookswebhooksHadisələrə abunə ol: platforma sizin URL-ə POST göndərəcək. Cavabdakı secret bir dəfə göstərilir.
url | qəbul üçün sizin https ünvanınız (məcburidir) |
events | mail.received, mail.delivered, mail.bounced, mail.complained |
{ "url": "https://ваш-сервер/webhook", "events": ["mail.received", "mail.bounced"] }{ "id": "…", "url": "…", "events": [...], "secret": "whsec_…" }
curl -X POST "https://api.spine.maxsystems.az/v1/webhooks" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://ваш-сервер/webhook","events":["mail.received","mail.bounced"]}'
const res = await fetch("https://api.spine.maxsystems.az/v1/webhooks", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "url": "https://ваш-сервер/webhook", "events": ["mail.received", "mail.bounced"] })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/webhooks",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"url":"https://ваш-сервер/webhook","events":["mail.received","mail.bounced"]}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"url":"https://ваш-сервер/webhook","events":["mail.received","mail.bounced"]}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/webhookswebhooksWebhook-larınızın siyahısı.
{ "webhooks": [ { "id": "…", "url": "…", "events": [...], "active": true } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/webhooks" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/webhooks", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/webhooks",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/webhooks/{id}webhooksWebhook-u sil.
{ "deleted": true }
curl -X DELETE "https://api.spine.maxsystems.az/v1/webhooks/{id}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/webhooks/{id}", {
method: "DELETE",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.delete(
"https://api.spine.maxsystems.az/v1/webhooks/{id}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webhooks/{id}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/webhooks/{id}/deliverieswebhooksWebhook çatdırılma jurnalı: status (pending/delivered/failed), kodlar, cəhdlər və dəqiq imzalanmış gövdə, imzanın sazlanması üçün əlverişlidir.
{ "deliveries": [ { "id": 42, "event": "mail.received", "status": "failed", "httpCode": 401, "attempts": 7, "payload": "{…}" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/webhooks/{id}/deliveries/{deliveryId}/redeliverwebhooksKonkret çatdırılmanı indi yenidən göndər (məsələn, imza yoxlayıcısını düzəltdikdən sonra).
{ "status": "delivered", "httpCode": 200 }
curl -X POST "https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
Telegram botları
/v1/telegram/mybotstelegram:botsMövcud botu tokeni ilə (BotFather-dan) platformaya qoş.
{ "token": "123456:ABC-…", "note": "бот проекта" }{ "id": "…", "botId": 123456, "username": "MyBot", "name": "My Bot" }
curl -X POST "https://api.spine.maxsystems.az/v1/telegram/mybots" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"123456:ABC-…","note":"бот проекта"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "token": "123456:ABC-…", "note": "бот проекта" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/telegram/mybots",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"token":"123456:ABC-…","note":"бот проекта"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"token":"123456:ABC-…","note":"бот проекта"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mybots/bulktelegram:botsKütləvi idxal: token siyahısı ilə (BotFather-dan) bir anda çoxlu bot qoş. tokens massiv və ya mətndir (hər sətirdə bir token).
{ "tokens": ["123456:AAA…", "234567:BBB…"] }{ "total": 2, "added": 2, "failed": 0, "results": [ { "ok": true, "username": "MyBot", "botId": 123456 } ] }
curl -X POST "https://api.spine.maxsystems.az/v1/telegram/mybots/bulk" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"tokens":["123456:AAA…","234567:BBB…"]}'
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots/bulk", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "tokens": ["123456:AAA…", "234567:BBB…"] })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/telegram/mybots/bulk",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"tokens":["123456:AAA…","234567:BBB…"]}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots/bulk");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"tokens":["123456:AAA…","234567:BBB…"]}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mybotstelegram:botsLayihənin botlarının siyahısı.
{ "bots": [ { "id": "…", "username": "MyBot", "webhookSet": true } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/telegram/mybots" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/telegram/mybots",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mybots/{id}telegram:botsBotun canlı statusu (getMe + webhook + əmrlər).
{ "username": "MyBot", "me": {...}, "webhook": {...}, "commands": [...] }
curl -X GET "https://api.spine.maxsystems.az/v1/telegram/mybots/{id}" \
-H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots/{id}", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/telegram/mybots/{id}",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots/{id}");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mybots/{id}/webhooktelegram:botsBotun update-lərini serverinizə yönləndir (SPINE onları Telegram-dan qəbul edib sizə ötürür).
{ "forwardUrl": "https://ваш-сервер/tg" }{ "hookUrl": "https://api.spine.maxsystems.az/v1/tg/hook/123456", "forwardUrl": "…" }
curl -X POST "https://api.spine.maxsystems.az/v1/telegram/mybots/{id}/webhook" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"forwardUrl":"https://ваш-сервер/tg"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots/{id}/webhook", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "forwardUrl": "https://ваш-сервер/tg" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/telegram/mybots/{id}/webhook",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"forwardUrl":"https://ваш-сервер/tg"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots/{id}/webhook");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"forwardUrl":"https://ваш-сервер/tg"}',
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mypresetstelegram:botsLayihəyə əlçatan hazır fabrik presetləri (ortaq + öz): əmrlər, webhook, profil.
{ "presets": [ { "id": "…", "name": "Поддержка", "forwardUrl": "https://…" } ] }
curl -X GET "https://api.spine.maxsystems.az/v1/telegram/mypresets" \ -H "Authorization: Bearer spine_sk_YOUR_KEY"
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mypresets", {
method: "GET",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY"
}
});
const data = await res.json();
import requests
r = requests.get(
"https://api.spine.maxsystems.az/v1/telegram/mypresets",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY"}
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mypresets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
/v1/telegram/mybots/create-linktelegram:botsFabrik: yeni bot yaratmaq üçün dip-link. İstifadəçi Telegram-da təsdiqləyir və bot layihəyə özü qoşulur. presetId ilə bot dərhal hazır şəkildə qurulur (əmrlər + webhook + profil).
{ "suggestedUsername": "myproject_bot", "presetId": "…(необязательно)" }{ "link": "https://t.me/newbot/spinemsbot/myproject_bot" }
curl -X POST "https://api.spine.maxsystems.az/v1/telegram/mybots/create-link" \
-H "Authorization: Bearer spine_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"suggestedUsername":"myproject_bot","presetId":"…(необязательно)"}'
const res = await fetch("https://api.spine.maxsystems.az/v1/telegram/mybots/create-link", {
method: "POST",
headers: {
"Authorization": "Bearer spine_sk_YOUR_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ "suggestedUsername": "myproject_bot", "presetId": "…(необязательно)" })
});
const data = await res.json();
import requests
r = requests.post(
"https://api.spine.maxsystems.az/v1/telegram/mybots/create-link",
headers={"Authorization": "Bearer spine_sk_YOUR_KEY", "Content-Type": "application/json"},
data='''{"suggestedUsername":"myproject_bot","presetId":"…(необязательно)"}'''
)
print(r.status_code, r.json())
$ch = curl_init("https://api.spine.maxsystems.az/v1/telegram/mybots/create-link");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer spine_sk_YOUR_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"suggestedUsername":"myproject_bot","presetId":"…(необязательно)"}',
]);
$data = json_decode(curl_exec($ch), true);
İmzanın yoxlanması və çatdırılmaHər çatdırılma X-Spine-Event (hadisə növü) və X-Spine-Signature: sha256=<hex> başlıqları olan POST-dur. Gövdə: {"event":"…","ts":"…","data":{…}}.
İmza = sorğunun xam gövdəsindən HMAC-SHA256 (baytlar gəldiyi kimi, JSON parse edilməzdən əvvəl). Açar whsec_… sirridir, olduğu kimi, tam sətir: onu base64-dən açmayın və prefiksi kəsməyin (bu Svix deyil). Nəticə hex-dir, sha256= prefiksi ilə. Sabit vaxtda müqayisə edin.
const crypto = require("crypto");
function verifySpineWebhook(secret, rawBody, sigHeader) {
// secret — строка ЦЕЛИКОМ, включая префикс whsec_ (не декодировать/не обрезать)
// rawBody — СЫРОЕ тело запроса (Buffer/строка), до JSON.parse
// sigHeader— значение заголовка X-Spine-Signature ("sha256=…")
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(sigHeader || ""), b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Bir dərhal cəhd; uğursuzluqda eksponensial backoff ilə durable təkrarlar (≈ 1 dəq, 5 dəq, 30 dəq, 2 saat, 6 saat, 12 saat sonra, ~21 saat ərzində 7 cəhdə qədər); növbə yenidən başlamağa tab gətirir. Uğur = sizin 2xx cavabınız. Çatdırılma jurnalı: GET /v1/webhooks/{id}/deliveries (status, kodlar və dəqiq imzalanmış gövdə görünür); konkret olanı yenidən göndər: POST /v1/webhooks/{id}/deliveries/{deliveryId}/redeliver. Tez cavab verin, ağır emalı fona atın (çatdırılma ən azı bir dəfədir, ona görə handler-i idempotent edin).
Gələn məktub üçün onun metadatasını (message), thread-in RFC başlıqlarını (rfc) və fırıldaq siqnallarını (security) qaytarırıq:
"data": {
"mailbox": "you@ваш-домен.az", "mailboxId": "c",
"message": {
"id": "eaaaaab", // per-mailbox id (НЕ глобальный, см. ниже)
"from": [{ "email": "sender@bank.az" }], "to": [{ "email": "you@ваш-домен.az" }],
"subject": "…", "receivedAt": "…", "preview": "…"
},
"rfc": {
"messageId": "<abc123@bank.az>", // RFC Message-ID — глобально-уникальный ключ письма
"inReplyTo": ["<prev@you.az>"], // на что это ответ
"references": ["<root@…>", "<prev@you.az>"] // цепочка треда
},
"security": {
"spam": { "isSpam": false, "score": 2.9, "status": "No", "label": "ham", "symbols": "DKIM_VALID(-0.5), …" },
"auth": { "spf": "pass", "dkim": "pass", "dmarc": "pass" }
}
}
İdentifikatorlar: message.id qısa per-mailbox id-dir (eyni məktubu API ilə oxumaq üçün), qlobal DEYİL. Qlobal unikal açar kimi (idempotentlik, thread) rfc.messageId istifadə edin; cavabları thread-ə rfc.inReplyTo/rfc.references üzrə bağlayın.
security: score spam-filtrin qiymətidir (rspamd üslubu; çox = daha şübhəli), isSpam həddi keçib-keçmədiyidir; spf/dkim/dmarc göndərənin həqiqiliyidir (pass/fail/none…). Əgər məktubda bu başlıqlar yoxdursa, sahə null ola bilər.
https://api.spine.maxsystems.az · maşın təsviri /v1/openapi.json