İçeriğe atla
Callmenta

Entegrasyon API

Müşteri ve randevu kayıtlarınızı Callmenta'ya gönderin, Callmenta'da olan olayları kendi adresinize alın.

Nasıl çalışır

Her entegrasyon hesabınızda bir bağlantı olarak durur. Veri iki yönde akabilir.

Yön Ne olur
Callmenta'ya gönderim Sisteminiz müşteri ya da randevu kaydını bağlantıya özel adrese JSON olarak gönderir. Callmenta kaydı mevcut kartla eşler ya da yenisini açar.
Callmenta'dan bildirim Callmenta'da bir müşteri kartı değiştiğinde, çağrı sonucu girildiğinde ya da randevu planlandığında belirlediğiniz adrese imzalı bir istek gelir.
Çift yön İkisi birden. Bir bağlantıdan gelen kayıt aynı bağlantıya geri gönderilmez, iki sistem birbirini döngüye sokmaz.

Tüm istek ve yanıt gövdeleri UTF-8 JSON'dur. Tarihler ISO 8601 biçimindedir, örneğin 2026-10-20T14:30:00+03:00.

Temel adres: https://callmenta.com/api

Bağlantıyı kurmak

Bağlantıyı Callmenta ekibi sizin için kurar. Kurulum için bize şunları iletin:

  • Verinin hangi yönde akacağı: yalnız Callmenta'ya gönderim, yalnız Callmenta'dan bildirim ya da ikisi birden
  • Bildirim alacaksanız Callmenta'nın istek göndereceği giden adresiniz. Adres https:// ile başlamalı ve internetten erişilebilir olmalı.
  • Almak istediğiniz olay türleri. Belirtmezseniz hepsi açılır.
  • Alan adlarınız bizimkinden farklıysa eşleme listesi
  • Aynı kayıt iki tarafta da değişirse hangisinin geçerli olacağı

Kurulum bitince size güvenli bir yoldan üç bilgi iletilir:

Bilgi Ne işe yarar
Müşteri adresi Müşteri kayıtlarını gönderdiğiniz adres. İçindeki anahtar bağlantınızın kimliğidir.
Randevu adresi Randevu kayıtlarını gönderdiğiniz adres. Aynı anahtarı taşır.
İmza anahtarı İsteklerinizi imzalamak ve bizden gelen bildirimleri doğrulamak için kullanılır.

İmza anahtarı yalnız kurulum anında bir kez görüntülenir, sonradan kimse okuyamaz. Kaybederseniz ya da başkasının eline geçtiğini düşünürseniz destek ekibimizden yenisini isteyin. Yeni anahtar verildiği anda eskisiyle imzalanan istekler reddedilir.

Çakışma kuralı

Kural Davranış
Son değişen kazanır Kaydınızdaki updated_at Callmenta'daki karttan yeni ya da eşitse güncellenir. updated_at göndermezseniz her zaman güncellenir.
Callmenta kazanır Var olan kart değişmez. Yalnız yeni kayıtlar açılır.
Dış sistem kazanır Gönderdiğiniz veri her zaman yazılır.

Hangi kural seçilirse seçilsin boş gönderilen alan mevcut veriyi silmez.

Kimlik ve imza

Adresteki anahtar bağlantınızı tanımlar. Gönderdiğiniz kayıtlar her zaman bu anahtarın ait olduğu hesaba yazılır. Gövdede başka bir şirket bilgisi gönderilse de dikkate alınmaz.

Her istek, imza anahtarınızla HMAC-SHA256 kullanılarak imzalanmalıdır.

Başlık Zorunlu Açıklama
Content-Type evet application/json
X-Callmenta-Signature evet sha256= ve ardından imzanın küçük harfli onaltılık değeri
X-Callmenta-Timestamp önerilir İsteğin gönderildiği an, Unix zamanı (saniye). Gönderirseniz 5 dakikadan eski istek reddedilir. Böylece ele geçirilen bir istek sonradan tekrar oynatılamaz.

İmza nasıl hesaplanır:

  • Zaman damgası gönderiyorsanız imzalanan metin {damga}.{ham gövde} olur.
  • Göndermiyorsanız imzalanan metin yalnız ham gövdedir.
  • İmzayı sunucuya gönderdiğiniz baytların tam aynısı üzerinden hesaplayın. Gövdeyi imzaladıktan sonra yeniden biçimlendirmeyin.
ANAHTAR="size iletilen adresteki anahtar"
SIR="imza anahtarınız"
GOVDE='{"customers":[{"external_id":"C-1042","name":"Ayşe Demir","phone":"+905321112233"}]}'
DAMGA=$(date +%s)
IMZA=$(printf '%s' "$DAMGA.$GOVDE" | openssl dgst -sha256 -hmac "$SIR" | sed 's/^.* //')

curl -X POST "https://callmenta.com/api/entegrasyon/$ANAHTAR/musteriler" \
  -H "Content-Type: application/json" \
  -H "X-Callmenta-Timestamp: $DAMGA" \
  -H "X-Callmenta-Signature: sha256=$IMZA" \
  --data-raw "$GOVDE"

Müşteri göndermek

POST /api/entegrasyon/{anahtar}/musteriler

Yeni müşteri açar ya da var olanı günceller. Tek istekte en fazla 500 kayıt gönderebilirsiniz. Kayıtları customers dizisinde gönderin. data dizisi ya da tek bir kayıt nesnesi de kabul edilir.

Alan Zorunlu Açıklama
external_id önerilir Kaydın sizin sisteminizdeki kimliği. Sonraki güncellemeler bu kimlikle eşlenir.
name bkz. not Ad soyad ya da firma adı
phone bkz. not Telefon. Uluslararası biçim önerilir: +905321112233
email bkz. not E-posta adresi
company_name hayır Müşterinin çalıştığı firma
city hayır Şehir
source hayır Kaydın kaynağı. Yalnız yeni kartta kullanılır. Gönderilmezse entegrasyon yazılır.
updated_at hayır Kaydın sizin taraftaki son değişiklik zamanı. "Son değişen kazanır" kuralında kullanılır.

name, phone ve email alanlarından en az biri dolu olmalı. Üçü de boş olan kayıt atlanır.

Eşleştirme sırası: önce bu bağlantıdan daha önce gelmiş aynı external_id, sonra aynı telefon, sonra aynı e-posta. Hiçbiri tutmazsa yeni kart açılır.

{
  "customers": [
    {
      "external_id": "C-1042",
      "name": "Ayşe Demir",
      "phone": "+905321112233",
      "email": "[email protected]",
      "company_name": "Örnek Lojistik",
      "city": "İzmir",
      "updated_at": "2026-10-13T09:15:00+03:00"
    }
  ]
}

Yanıt:

{
  "success": true,
  "received": 1,
  "created": 1,
  "updated": 0,
  "skipped": 0,
  "failed": 0,
  "run_id": 58213,
  "message": null
}

run_id, isteğin bizim kayıtlarımızdaki numarasıdır. Destek isterken bu numarayı paylaşın.

Randevu göndermek

POST /api/entegrasyon/{anahtar}/randevular

Randevu açar, günceller, erteler ya da durumunu değiştirir. Kayıtları appointments dizisinde gönderin. data dizisi ya da tek kayıt nesnesi de kabul edilir. Tek istekte en fazla 500 kayıt gönderilebilir. Aynı randevu iki kez gelirse ikinci bir randevu açılmaz, var olan güncellenir.

Alan Zorunlu Açıklama
external_id evet Randevunun sizin sisteminizdeki kimliği, en fazla 120 karakter
starts_at yeni kayıtta Başlangıç zamanı
ends_at hayır Bitiş zamanı
status hayır Randevu durumu, değerler aşağıda
new_starts_at erteleme status değeri rescheduled olduğunda yeni başlangıç zamanı
appointment_id hayır Randevu Callmenta'da açıldıysa Callmenta'nın verdiği numara. Olay bildirimlerinde size gelir.
customer_external_id bkz. not Müşterinin sizin sisteminizdeki kimliği
phone bkz. not Müşterinin telefonu
email bkz. not Müşterinin e-postası
name bkz. not Müşterinin adı. customer_name da kabul edilir.
title hayır Randevunun konusu. topic da kabul edilir.
type hayır Randevu türü
mode hayır Görüşme şekli, örneğin yüz yüze ya da çevrim içi
location hayır Adres ya da yer
join_url hayır Çevrim içi görüşmenin katılım bağlantısı
assigned_email hayır Randevuyu üstlenecek kullanıcının Callmenta'daki e-postası
note hayır Not
reason hayır Durum değişikliğinin gerekçesi, örneğin iptal nedeni

Yeni randevuda müşteri customer_external_id, telefon ya da e-postayla aranır. Bulunamazsa ve name ile phone birlikte geldiyse yeni müşteri kartı açılır. Aksi halde kayıt musteri_bulunamadi hatasıyla döner.

Durum değerleri

Gönderdiğiniz değer Callmenta'daki karşılığı
scheduled, created, planned Planlandı
confirmed Onaylandı
attended, arrived Geldi
completed Tamamlandı
no_show Gelmedi
cancelled, canceled İptal
rescheduled, postponed Ertelendi. Yeni zamanı new_starts_at ile gönderin.

İptal ya da gelmedi olarak işaretlenmiş bir randevuya scheduled gönderirseniz randevu yeniden açılır.

{
  "appointments": [
    {
      "external_id": "R-77810",
      "starts_at": "2026-10-20T14:30:00+03:00",
      "ends_at": "2026-10-20T15:00:00+03:00",
      "status": "confirmed",
      "customer_external_id": "C-1042",
      "name": "Ayşe Demir",
      "phone": "+905321112233",
      "title": "Ürün tanıtımı",
      "mode": "online",
      "join_url": "https://toplanti.ornek.com/abc",
      "assigned_email": "[email protected]"
    }
  ]
}

Erteleme:

{ "external_id": "R-77810", "status": "rescheduled", "new_starts_at": "2026-10-22T11:00:00+03:00", "reason": "Müşteri talebi" }

Kısmi başarı yanıtı (207):

{
  "success": false,
  "received": 2,
  "created": 1,
  "updated": 0,
  "skipped": 0,
  "failed": 1,
  "errors": [
    { "sira": 1, "external_id": "R-77811", "hata": "starts_at_gerekli" }
  ],
  "run_id": 58214
}

Kayıt hata kodları

Kod Anlamı
external_id_gerekli external_id yok ya da 120 karakterden uzun
starts_at_gerekli Yeni randevu için başlangıç zamanı gönderilmedi
tarih_gecersiz Tarih okunamadı. ISO 8601 kullanın.
durum_taninmiyor status değeri tabloda yok
musteri_bulunamadi Müşteri eşlenemedi ve yeni kart açmak için ad ile telefon birlikte gelmedi
gecersiz_kayit Dizideki öğe bir nesne değil
islenemedi Beklenmeyen bir sorun oldu. run_id ile destek ekibimize yazın.

sira, kaydın gönderdiğiniz dizideki sırasıdır ve 0'dan başlar. Yanıtta en fazla 20 hata ayrıntısı yer alır.

Yanıtlar ve hatalar

Kod Ne zaman Ne yapmalı
200 Tüm kayıtlar işlendi Bir şey yapmanız gerekmez
207 Bazı kayıtlar işlenemedi Yalnız hatalı kayıtları düzeltip yeniden gönderin
401 Anahtar geçersiz, bağlantı kapalı ya da gönderime kapalı. İmza tutmuyor ya da damga 5 dakikadan eski. Adresi, imza anahtarını ve sunucu saatinizi kontrol edin
422 Gövdede kayıt yok ya da 500'den fazla kayıt var Gövdeyi düzeltin, büyük listeleri parçalayın
429 İstek sınırı aşıldı retry_after saniye bekleyip yeniden deneyin

İstek sınırları

  • Bağlantı başına dakikada 60 istek
  • IP adresi başına dakikada 120 istek
  • İstek başına en fazla 500 kayıt

Bu sınırlarla bir bağlantı dakikada 30.000 kayda kadar aktarabilir (60 istek × 500 kayıt). Büyük ilk aktarımlarda kayıtları 500'lük parçalara bölün ve parçalar arasında kısa bir ara verin.

Olay bildirimleri

Bildirim almayı seçtiyseniz Callmenta, olaylar olduğu anda giden adresinize POST isteği gönderir. Hangi olayları alacağınız kurulumda belirlenir. Hepsini seçerseniz ileride eklenecek olay türleri de otomatik gelir.

POST https://sizin-adresiniz.com/callmenta
Content-Type: application/json
User-Agent: Callmenta-Integration/1.0
X-Callmenta-Event: call.disposition_recorded
X-Callmenta-Signature: sha256=5f2c…

{
  "event": "call.disposition_recorded",
  "sent_at": "2026-10-13T11:42:07+03:00",
  "data": { … }
}

Giden isteklerdeki X-Callmenta-Signature, imza anahtarınızla ham gövdenin HMAC-SHA256 değeridir. Giden isteklerde zaman damgası yoktur, imza yalnız gövde üzerinden hesaplanır. Doğrulamayı ham gövde üzerinde, JSON'u ayrıştırmadan önce yapın. Karşılaştırmayı sabit sürede çalışan bir fonksiyonla yapın.

Aynı olay yeniden denendiğinde aynı data.olay_id ile gelir. Bu kimliği saklayıp ikinci kez gelirse yok sayın. Müşteri kartı bildirimlerinde aynı amaçla Idempotency-Key başlığı gönderilir.

Olay türleri

Olay Ne zaman gelir
customer.upserted Müşteri kartı açıldığında ya da değiştiğinde
call.disposition_recorded Temsilci bir çağrının sonucunu girdiğinde
followup.scheduled Bir geri arama ya da takip planlandığında
lead.created Reklam formundan yeni başvuru geldiğinde
appointment.scheduled Randevu planlandığında
appointment.updated Randevunun durumu ya da bilgisi değiştiğinde
outbound.outcome_recorded Arama listesindeki bir kişi için sonuç girildiğinde
ping Kurulumda ya da destek sırasında bağlantı sınandığında

Örneklerdeki değerler temsilidir. Sonuç kodu, kategori ve aşama adları hesabınızda tanımlı listelerden gelir. İleride gövdelere yeni alanlar eklenebilir, tanımadığınız alanları yok sayın.

customer.upserted

{
  "id": 48211,
  "external_id": "C-1042",
  "name": "Ayşe Demir",
  "phone": "+905321112233",
  "email": "[email protected]",
  "company_name": "Örnek Lojistik",
  "city": "İzmir",
  "stage": "teklif",
  "source": "entegrasyon",
  "updated_at": "2026-10-13T11:40:12+03:00"
}

Bu isteğe JSON yanıtta id alanı dönerseniz Callmenta bu değeri müşterinin sizdeki kimliği olarak saklar ve sonraki bildirimlerde external_id olarak geri gönderir.

call.disposition_recorded

{
  "olay_id": "9b1e6c1a-5d0f-4a7e-9f1e-2a8c0b7d4e11",
  "company_id": 1001,
  "call_log_id": 903114,
  "customer_id": 48211,
  "phone": "+905321112233",
  "direction": "inbound",
  "disposition": "satis",
  "disposition_label": "Satış",
  "category": "olumlu",
  "reason": null,
  "topic": "Fiyat bilgisi",
  "note": "Teklif e-postayla gönderilecek.",
  "callback_at": null,
  "agent": { "id": 512, "name": "Temsilci Adı" },
  "recorded_at": "2026-10-13T11:42:06+03:00"
}

Sonuç arama listesinden girildiyse ayrıca name, source: "outbound_list" ve list_id gelir, call_log_id boş olur.

followup.scheduled

{
  "olay_id": "…",
  "company_id": 1001,
  "source": "call",
  "call_log_id": 903114,
  "customer_id": 48211,
  "phone": "+905321112233",
  "due_at": "2026-10-14T10:00:00+03:00",
  "topic": "Teklif dönüşü",
  "disposition": "geri_ara",
  "agent": { "id": 512, "name": "Temsilci Adı" },
  "recorded_at": "…"
}

Arama listesinden gelen takiplerde source değeri outbound_list olur, list_id, item_id ve attempt eklenir.

lead.created

{
  "olay_id": "…",
  "company_id": 1001,
  "source": "meta_reklam",
  "lead_id": 2210,
  "customer_id": 48230,
  "new_customer": true,
  "name": "Mehmet Kaya",
  "phone": "+905339998877",
  "email": "[email protected]",
  "campaign": { "id": "…", "name": "Ekim kampanyası" },
  "adset": { "id": "…", "name": "…" },
  "ad": { "id": "…", "name": "…" },
  "form": { "id": "…", "name": "Bilgi formu" },
  "platform": "instagram",
  "suspicion_score": 12,
  "fields": { "ilce": "Bornova" },
  "recorded_at": "…"
}

suspicion_score başvurunun sahte olma olasılığını gösterir, değer büyüdükçe olasılık artar. fields formdaki ek soruların yanıtlarıdır.

appointment.scheduled ve appointment.updated

{
  "olay_id": "…",
  "company_id": 1001,
  "previous_status": "planlandi",
  "action": "bilgi",
  "appointment_id": 3381,
  "customer_id": 48211,
  "phone": "+905321112233",
  "name": "Ayşe Demir",
  "starts_at": "2026-10-20T14:30:00+03:00",
  "ends_at": "2026-10-20T15:00:00+03:00",
  "status": "onaylandi",
  "location": "https://toplanti.ornek.com/abc",
  "mode": "online",
  "join_url": "https://toplanti.ornek.com/abc",
  "topic": "Ürün tanıtımı",
  "type": "Tanıtım",
  "module_name": "Randevu",
  "assigned": { "id": 512, "name": "Temsilci Adı", "email": "[email protected]" },
  "external_id": "R-77810",
  "source": "dis_sistem",
  "recorded_at": "…"
}

status şu değerlerden birini alır: planlandi, onaylandi, geldi, tamamlandi, gelmedi, iptal, ertelendi. appointment.scheduled olayında previous_status boş gelir. action yalnız güncellemede gelir: durum değiştiyse yeni durum, yalnız bilgi değiştiyse bilgi yazar. Randevuyu siz gönderdiyseniz aynı bağlantıya bildirim gelmez.

outbound.outcome_recorded

{
  "company_id": 1001,
  "list_id": 88,
  "list": "Ekim yenileme listesi",
  "item_id": 120455,
  "customer_id": 48211,
  "name": "Ayşe Demir",
  "phone": "+905321112233",
  "outcome": "ulasildi_olumlu",
  "outcome_label": "Ulaşıldı, olumlu",
  "status": "tamamlandi",
  "attempt": 2,
  "next_attempt_at": null,
  "note": "Yenileme onaylandı.",
  "fields": { "police_no": "…" },
  "agent": { "id": 512, "name": "Temsilci Adı", "email": "[email protected]" },
  "recorded_at": "…"
}

fields, listeyi yüklerken eklediğiniz sütunlardır. Bu olay olay seçiminden bağımsız olarak her zaman gönderilir.

ping

{ "event": "ping", "sent_at": "2026-10-13T11:00:00+03:00" }

2xx yanıt verirseniz sınama başarılı sayılır.

Teslim ve yeniden deneme

  • Adresiniz 15 saniye içinde yanıt vermelidir. Uzun işleri kuyruğa alıp hemen 200 dönün.
  • Her 2xx yanıt teslim edildi sayılır.
  • Bağlantı hatası, zaman aşımı, 408, 429 ve 5xx yanıtlarda istek yeniden denenir. Toplam 3 deneme yapılır: ilkinden 1 dakika, ikincisinden 5 dakika sonra.
  • 429 dışındaki 4xx yanıtlar ret sayılır ve yeniden denenmez.
  • Yönlendirmeler izlenmez. 301 ya da 302 dönen adres başarısız sayılır.
  • Yerel ağ ve özel IP adreslerine istek gönderilmez. Adres internetten erişilebilir olmalıdır.
  • Olaylar sırasız gelebilir. Sıralama için recorded_at alanını kullanın.

İmza doğrulama örnekleri

Callmenta'dan gelen isteği doğrulamak için aşağıdaki örnekleri kullanabilirsiniz. İmzayı her zaman ham gövde üzerinden hesaplayın.

PHP:

$govde  = file_get_contents('php://input');
$gelen  = $_SERVER['HTTP_X_CALLMENTA_SIGNATURE'] ?? '';
$beklenen = 'sha256=' . hash_hmac('sha256', $govde, getenv('CALLMENTA_IMZA_ANAHTARI'));

if (! hash_equals($beklenen, $gelen)) {
    http_response_code(401);
    exit;
}
$olay = json_decode($govde, true);
http_response_code(200);

Node.js (Express):

const crypto = require('crypto');

app.post('/callmenta', express.raw({ type: 'application/json' }), (req, res) => {
  const beklenen = 'sha256=' + crypto
    .createHmac('sha256', process.env.CALLMENTA_IMZA_ANAHTARI)
    .update(req.body)
    .digest('hex');
  const gelen = req.get('X-Callmenta-Signature') || '';
  const esit = gelen.length === beklenen.length &&
    crypto.timingSafeEqual(Buffer.from(gelen), Buffer.from(beklenen));
  if (!esit) return res.sendStatus(401);

  const olay = JSON.parse(req.body.toString('utf8'));
  res.sendStatus(200);
});

Python (Flask):

import hmac, hashlib, os
from flask import request, abort

@app.post("/callmenta")
def callmenta():
    govde = request.get_data()
    beklenen = "sha256=" + hmac.new(
        os.environ["CALLMENTA_IMZA_ANAHTARI"].encode(), govde, hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(beklenen, request.headers.get("X-Callmenta-Signature", "")):
        abort(401)
    olay = request.get_json()
    return "", 200

Callmenta'ya imzalı istek göndermek, Python:

import hmac, hashlib, json, os, time, requests

anahtar = os.environ["CALLMENTA_ADRES_ANAHTARI"]
sir = os.environ["CALLMENTA_IMZA_ANAHTARI"].encode()
govde = json.dumps({"customers": [{"external_id": "C-1042", "name": "Ayşe Demir",
                                    "phone": "+905321112233"}]}, ensure_ascii=False).encode()
damga = str(int(time.time()))
imza = hmac.new(sir, damga.encode() + b"." + govde, hashlib.sha256).hexdigest()

yanit = requests.post(
    f"https://callmenta.com/api/entegrasyon/{anahtar}/musteriler",
    data=govde,
    headers={"Content-Type": "application/json",
             "X-Callmenta-Timestamp": damga,
             "X-Callmenta-Signature": f"sha256={imza}"},
    timeout=30,
)
print(yanit.status_code, yanit.json())

Sık sorulanlar

Hep 401 alıyorum

Önce adresi size iletildiği gibi, eksiksiz kullandığınızı kontrol edin. Sonra imzayı gönderdiğiniz baytların aynısı üzerinden hesapladığınızdan emin olun. Damga gönderiyorsanız sunucu saatinizin doğru olduğunu kontrol edin.

Anahtarım başkasının eline geçti

Destek ekibimize hemen yazın. İmza anahtarı yenilenir. Adresin de değişmesi gerekiyorsa bağlantı yeniden kurulur ve eski adres o anda geçersiz olur.

Aynı müşteri iki kez açıldı

Her kayıtta external_id gönderin ve telefonu her seferinde aynı biçimde yazın. Eşleştirme önce dış kimliğe, sonra telefona, sonra e-postaya bakar.

Hazır CRM bağlantıları var mı

Evet. HubSpot, Salesforce, Pipedrive, Zoho CRM, Bitrix24, Zendesk, Freshdesk ve Google Kişiler için hazır bağlantılarımız var. Bunlar kod yazmadan, sizin hesap bilgilerinizle kurulur.

Kurulumda yardım ister misiniz?

Bağlantıyı ekibimizle birlikte kurabiliriz. Sorunuzu iletin, size dönelim.