Developer API endpoint-lərini işlətmək: nümunələr, səhifələmə, idempotency

Son yeniləmə: 11 noyabr 2026 · 8 dəq oxunur

Endpoint API-nin bir ünvanı və bir əməliyyatıdır: metod (GET oxumaq, POST yaratmaq, PATCH dəyişmək, DELETE silmək) və yol. Bütün endpoint-lər, parametrləri və cavab nümunələri developer.clomni.ai-da «API reference» səhifəsindədir. Hər endpoint-in yanında lazım olan scope-lar yazılıb, onlardan biri kifayətdir. Siyahıda olmayan endpoint developer tokenlərinə bağlıdır və 403 endpoint_not_available qaytarır. Hansı işə hansı endpoint və scope lazım olduğu «Hansı scope lazımdır: istəyinizə görə scope və endpoint seçimi» məqaləsində və «Scope-lar və endpoint-lər: …» məqalələrindədir.

Addımlar

  1. 1

    Sorğu necə qurulur

    Ünvan https://api.clomni.ai/v1 ilə başlayır, token Authorization: Bearer <token> başlığında gedir, gövdə JSON-dur (Content-Type: application/json). Ünvanda workspace nömrəsi yazılmır.

    • Söhbətin API-dəki id-si paneldə görünən nömrə ilə eynidir: «söhbət 1042» GET /conversations/1042 deməkdir.
    • Adi endpoint-lər vaxtı Unix saniyəsi ilə, sinxron endpoint-ləri ISO 8601 ilə (2026-11-08T16:00:00Z) qaytarır. Vaxt zonası UTC-dir.
    • Telefon beynəlxalq formatda yazılır: +994501234567.
  2. 2

    Söhbətləri və mesajları oxuyun

    GET /conversations (scope conversations:read) söhbətləri 25-lik səhifələrlə qaytarır. Parametrlər: status (open, resolved, pending, snoozed, all, default open), assignee_type (me, unassigned, assigned, all), inbox_id, page.

    curl "https://api.clomni.ai/v1/conversations?status=open&page=1" \
      -H "Authorization: Bearer $CLOMNI_TOKEN"
    const res = await fetch("https://api.clomni.ai/v1/conversations?status=open&page=1", {
      headers: { Authorization: `Bearer ${process.env.CLOMNI_TOKEN}` },
    });
    const { data } = await res.json();
    for (const c of data.payload) console.log(c.id, c.status, c.meta.sender.name);
    import os, requests
    res = requests.get("https://api.clomni.ai/v1/conversations", params={"status": "open", "page": 1},
                       headers={"Authorization": f"Bearer {os.environ['CLOMNI_TOKEN']}"}, timeout=10)
    for c in res.json()["data"]["payload"]:
        print(c["id"], c["status"], c["meta"]["sender"]["name"])

    Söhbətin can_reply sahəsi indi müştəriyə sərbəst mesaj yazmaq olub-olmadığını göstərir. Mesajlar: GET /conversations/{conversation_id}/messages (scope messages:read) son 20 mesajı verir, daha köhnələri üçün ?before=<ən kiçik id>. message_type: 0 gələn, 1 gedən, 2 sistem qeydi, 3 şablon. status: sent, delivered, read, failed.

  3. 3

    Cavab yazın və söhbəti idarə edin

    POST /conversations/{conversation_id}/messages, scope messages:send:

    curl -X POST "https://api.clomni.ai/v1/conversations/1042/messages" \
      -H "Authorization: Bearer $CLOMNI_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 6f1c2a9e-3b7d-4f0a-9c55-0e8b1d2a7f41" \
      -d '{"content": "Salam, sifarişiniz bu gün çatdırılacaq."}'

    Kanal mesajı fonda göndərir, status əvvəlcə sent olur, nəticə sonra message.updated webhook-u ilə gəlir. Alınmayanda səbəb content_attributes.external_error-dadır. Müştərinin görmədiyi daxili qeyd üçün "private": true göndərin (scope notes:write).

    • Bağlamaq, açmaq: POST /conversations/{conversation_id}/toggle_status ilə { "status": "resolved" } (scope conversations:write).
    • Təyin etmək: POST /conversations/{conversation_id}/assignments ilə { "assignee_id": 12 } və ya { "team_id": 3 } (scope conversations:assign).
    • Operator və komanda siyahısı: GET /agents, GET /teams.
  4. 4

    Kontakt yaradın və axtarın

    POST /contacts (scope contacts:write):

    curl -X POST "https://api.clomni.ai/v1/contacts" \
      -H "Authorization: Bearer $CLOMNI_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "Leyla Həsənova", "phone_number": "+994501234567", "identifier": "crm-10045"}'

    identifier sizin sistemdəki ID-dir və workspace daxilində unikaldır. PATCH /contacts/{contact_id} yalnız göndərdiyiniz sahələri dəyişir. GET /contacts/search?q=crm-10045 ad, e-poçt, telefon və identifier üzrə axtarır. Eyni e-poçt və ya telefonla ikinci kontakt 422 qaytarır: əvvəl axtarın, sonra yeniləyin. custom_attributes açarları workspace-də əvvəlcədən yaradılmalıdır.

  5. 5

    Səhifələmə: adi siyahılar

    • GET /conversations: page (1-dən), 25-lik səhifə, cavab data.meta və data.payload.
    • GET /contacts: page, 15-lik səhifə, cavab meta.count, meta.current_page, payload.
    • GET /conversations/{conversation_id}/messages: before=<message_id>, hər dəfə 20 mesaj.

    Bu siyahılar ekranda göstərmək üçündür. Məlumatı tam köçürmək üçün onları gəzməyin: səhifələr arasında yeni söhbət gələndə sıra sürüşür və obyektlər itə bilər.

  6. 6

    Sinxron: məlumatı öz bazanıza köçürün

    GET /sync/conversations (conversations:read), GET /sync/messages (messages:read), GET /sync/contacts (contacts:read). Parametrlər: updated_since (ISO 8601), after (əvvəlki cavabın next_cursor-u), limit (1-100, default 50). Cavab: data, next_cursor, has_more.

    1. İlk yükləmə: updated_since olmadan başlayın, has_more: false olana qədər after=next_cursor ilə davam edin.
    2. Aldığınız ən böyük updated_at-ı saxlayın.
    3. Növbəti dəfə updated_since = saxlanmış vaxt mənfi 2 dəqiqə.
    4. Obyekti id ilə yazın (upsert), dublikatı atın.
    5. Yeniliyi webhook ilə dərhal alın, sinxronu 5-15 dəqiqədən bir işlədin.

    Sinxron obyektlərində söhbətin id-si daxili ID-dir, paneldəki nömrə number-də (mesajda conversation_number) olur. Fayl linkləri qısa ömürlüdür. Sinxron dəqiqədə 60 sorğu ilə məhdudlaşır. Bütün tarixçəni bir dəfə köçürmək üçün POST /exports (exports:run, eyni anda 1 iş, gündə 6) daha uyğundur.

  7. 7

    Təkrar göndərməyə qarşı: Idempotency-Key

    Şəbəkə kəsiləndə POST-un gedib-getmədiyini bilmək olmur. Hər yeni əməliyyat üçün yeni UUID yaradıb Idempotency-Key başlığında göndərin, təkrar cəhddə eynisini göndərin.

    • Bütün /v1 POST-larında işləyir, /oauth/* xaric. Açar 1-255 simvoldur, app və workspace üzrə 24 saat saxlanır.
    • Eyni açar, eyni gövdə: əməliyyat təkrarlanmır, saxlanmış cavab Idempotency-Replayed: true ilə qayıdır.
    • Eyni açar, fərqli gövdə: 409 idempotency_key_reused. Birinci sorğu hələ gedirsə: 409 idempotency_key_in_progress.
    • 5xx cavablar saxlanmır, eyni açarla təkrar etmək olar.

    Mesajda əlavə olaraq content_attributes.client_echo_id də var: eyni söhbətdə 24 saat ərzində eyni dəyərlə gələn sorğu yeni mesaj yaratmır.

  8. 8

    Hadisə lenti: GET /v1/events

    Son 30 günün hadisələrini (webhook-dakı kimi, eyni id ilə) köhnədən yeniyə qaytarır. Scope events:read və mövzunun oxuma scope-u (messages:read, conversations:read, contacts:read), yoxsa siyahı boş gəlir. Parametrlər: types (məsələn message.created,contact.updated), after, limit (1-100). Serverinizin açıq ünvanı yoxdursa lenti hər dəqiqə oxuyun, varsa webhook-un qaçırdığını buradan götürün.

Sənəd