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
200dönün. - Her 2xx yanıt teslim edildi sayılır.
- Bağlantı hatası, zaman aşımı,
408,429ve5xxyanıtlarda istek yeniden denenir. Toplam 3 deneme yapılır: ilkinden 1 dakika, ikincisinden 5 dakika sonra. 429dışındaki4xxyanıtlar ret sayılır ve yeniden denenmez.- Yönlendirmeler izlenmez.
301ya da302dö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_atalanı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.