API Dokümantasyonu
KargoSeç API ile kargo fiyat karşılaştırma, gönderi oluşturma ve takip işlemlerini uygulamanıza entegre edin.
API Anahtarı Gerekli
API'yi kullanmak için önce ücretsiz hesap oluşturun, ardından giriş yaparak API Anahtarları panelinden anahtarınızı alın.
Başlarken
Kargo Seç API v2, kargo fiyat karşılaştırma ve gönderi oluşturma işlemlerini programatik olarak yapmanızı sağlar.
Tüm istekler https://kargosec.com/api/v2 base URL üzerinden yapılır.
Base URL
https://kargosec.com/api/v2
Format
JSON (application/json)
Kimlik Doğrulama
Tüm API isteklerinde X-Api-Key header'ı göndermeniz gerekir.
API anahtarınızı
giriş yapıp API Anahtarları panelinden
alabilirsiniz.
curl -X GET "https://kargosec.com/api/v2/account/info" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Accept: application/json"
Önemli: API anahtarınızı gizli tutun. Asla istemci tarafı kodda (JavaScript, mobil uygulama) kullanmayın.
Hızlı Başlangıç
-
1
API anahtarını al
Panelinizdeki API Anahtarları sayfasından
ksk_...anahtarınızı oluşturun. -
2
İl, ilçe ve firma ID'lerini çek
GET /locations/provinces,/locations/districts/{province_id}ve/cargo-companiesile gerekli ID'leri alın. -
3
Fiyatı önizle
POST /prices/compareile tüm firmaların indirimli fiyatını karşılaştırın. -
4
Gönderiyi oluştur ve etiketi al
POST /shipmentstek istekte gönderiyi açar, ücreti bakiyenizden düşer ve yazdırılabilir etiketi aynı yanıtta döndürür.
Tek Tuş Etiket
Sitenize sipariş düştüğünde tek istek yeter: gönderiyi açar, ücreti tahsil eder ve yazdırılabilir kargo etiketini aynı yanıtta döndürür.
Çıkış adresini biz tamamlarız
Depo adresiniz hesabınızda kayıtlıdır; sender_*
alanlarını göndermenize gerek yok. Birden fazla deponuz varsa
sender_address_code ile seçersiniz.
Alıcı için il/ilçe ADI yeter
Sipariş kaydınızdaki "İstanbul" / "Kadıköy" metnini olduğu gibi yollayın. ID listesi tutmanız gerekmez; plaka kodu da kabul edilir.
Taşıyıcıyı biz seçeriz
Hesabınızdaki varsayılan firma kullanılır. Dilerseniz istekte
carrier alanına
"hepsijet",
"ups" ya da
"cheapest" yazın.
İstek
POST /api/v2/shipments
X-Api-Key: ksk_...
Content-Type: application/json
{
"order_reference": "SIP-2026-10428",
"receiver_name": "Veli Alıcı",
"receiver_phone": "05551112233",
"receiver_address": "Kızılay Mah. Atatürk Bul. No:5 D:3",
"receiver_province": "Ankara",
"receiver_district": "Çankaya",
"width": 30, "length": 40, "height": 30,
"weight": 5,
"quantity": 1,
"content_description": "Tekstil ürünü"
}
Yanıt — 201 Created
{
"success": true,
"duplicate": false,
"data": {
"id": 4821,
"order_reference": "SIP-2026-10428",
"tracking_number": "KS7QWERTY",
"carrier": {
"id": 3, "name": "HepsiJet", "integration_code": "hepsijet",
"tracking_number": "KGS000004821", "synced": true
},
"payment": { "method": "balance", "paid": true, "amount": 89.50, "balance": 1910.50 },
"label": {
"status": "ready",
"content_type": "application/pdf",
"base64": "JVBERi0xLjQK...",
"url": "https://kargosec.com/api/v2/shipments/4821/label-download?signature=...",
"expires_at": "2026-09-24T12:00:00+00:00"
}
}
}
label.base64 doğrudan yazıcıya gönderilebilen
10×15 cm PDF'tir. label.url ise 24 saat geçerli,
oturum gerektirmeyen imzalı bağlantıdır — depo personeline verebilirsiniz.
Dikkat: kök tracking_number firmaya basılana kadar KargoSeç iç kodudur;
kargo barkodu carrier.tracking_number (ya da
carrier_tracking_number) alanındadır.
Bakiyeniz yetmezse ne olur?
Gönderi kaybolmaz. "Ödeme bekliyor" olarak açılır ve
402 ile birlikte kredi kartı ödeme bağlantısı döner.
Ödeme tamamlandığı anda gönderi taşıyıcıya iletilir ve size
shipment.label_ready webhook'u gelir.
HTTP/1.1 402 Payment Required
{
"success": false,
"error_code": "payment_required",
"message": "Bakiye yetersiz (mevcut 10,00 TL, gereken 89,50 TL). Ödeme bağlantısı oluşturuldu; ...",
"data": {
"id": 4822,
"payment": {
"method": "card", "paid": false, "amount": 89.50, "balance": 10.00,
"payment_url": "https://kargosec.com/odeme/a1b2c3...",
"payment_expires_at": "2026-09-26T12:00:00+00:00"
},
"label": { "status": "awaiting_payment" }
}
}
Çift tıklama koruması — order_reference
Kendi sipariş numaranızı order_reference
(ya da Idempotency-Key başlığı) olarak gönderin.
Aynı anahtarla gelen ikinci istek yeni kargo açmaz ve ikinci kez tahsilat yapmaz;
ilk gönderiyi (ve etiketini) 200 OK +
"duplicate": true ile döndürür.
Butona iki kez basılması, ağ zaman aşımı sonrası tekrar denemeniz ya da kuyruğunuzun aynı siparişi
yeniden işlemesi böylece güvenlidir. Şiddetle tavsiye edilir.
Etiket her zaman anında gelir mi?
Neredeyse her zaman. Taşıyıcının sistemi o an yavaşsa yanıt
"label": { "status": "pending" } döner —
gönderi ve ödeme geçerlidir, yalnızca etiket birkaç saniye gecikir.
Döngüye girmeyin: etiket hazır olduğunda
shipment.label_ready webhook'u gönderilir.
Webhook kullanmıyorsanız
GET /shipments/{id}/label ile sorgulayabilirsiniz.
Etiket kuralı ve yeniden entegrasyon rehberi (güncelleme: 8 Ekim 2026)
Kutuya yapıştıracağınız etiket yalnızca kargo firmasının canlı etiketi olmalıdır. Entegrasyonlu firmalarda (HepsiJet, UPS, Yurtiçi, KolayGelsin, Sürat, PTT) KargoSeç şablonu asla etiket olarak verilmez; gönderi firmaya basılana kadar etiket üretilmez. Sizin tarafınızda uygulayacağınız 4 kural:
- Etiketi kendiniz çizmeyin. Yalnızca
label.base64,label.urlya daGET /shipments/{id}/labelçıktısını yazdırın. tracking_numberher zaman kargo barkodu değildir. Gönderi firmaya basılana dek KargoSeç iç kodudur (KS…) ve ödemeden sonra değişir. Barkod olarak yalnızcacarrier_tracking_numberkullanın;tracking_number_is_carrierfalseiken o kodla etiket basmayın, müşteriye barkod diye göstermeyin.- Etiket durumunu
label_statusile okuyun (aşağıdaki tablo). Yalnızcareadyiken yazdırın. - 402 bir hata değildir. Bakiye yetmediyse gönderi "ödeme bekliyor" açılır;
payment.payment_url'yi müşterinize gösterin. Ödeme gelincelabel_statusreadyolur veshipment.label_readywebhook'u gelir.
| label_status | Anlamı | Ne yapmalı |
|---|---|---|
| awaiting_payment | Ödeme yok | Ödeme bağlantısını gösterin; etiket basmayın. |
| pending | Ödendi, firmaya iletiliyor | Bekleyin (webhook gelir) ya da birkaç saniye sonra tekrar sorgulayın. Döngüye girmeyin. |
| ready | Etiket hazır | label_url'yi açın ya da /label'den PDF alın ve yazdırın. |
| unavailable | Gönderi iptal | Etiket yok. |
label_status, label_url, carrier_tracking_number ve tracking_number_is_carrier
alanları GET /shipments, GET /shipments/{id} ve gönderi oluşturma yanıtındaki gönderi nesnesinde bulunur.
Mevcut hiçbir alan değişmedi; yalnızca bunlar eklendi.
Hesap varsayılanlarınızı görmek için
GET /account/info hangi taşıyıcının ve hangi çıkış
adresinin varsayılan olduğunu defaults altında döndürür.
Tanımlı tüm depolarınız ve kodları için
GET /account/addresses.
İstek Limiti ve IP Kısıtı
İstek limiti iki katmanda uygulanır. Efektif limitiniz bu ikisinin küçüğüdür.
1. Rota katmanı
Tüm /api/v2 uçları için
dakikada 120 istek.
2. Hesap katmanı
API anahtarınıza tanımlı limit — varsayılan dakikada 60 istek. Hesabınıza göre yükseltilebilir.
Limit aşıldığında 429 Too Many Requests döner.
Sayaç 60 saniyelik pencerelerle sıfırlanır.
IP kısıtı: Hesabınıza izinli IP listesi (allowed_ips)
tanımlıysa, bu listede olmayan bir IP'den gelen istek
403 Forbidden alır.
Liste boşsa IP kısıtı uygulanmaz. Sunucunuzun çıkış IP'si değiştiğinde listeyi güncellemeyi unutmayın.
Endpoint'ler
Hesap
/api/v2/account/info
Hesap bilgisi ve bakiye sorgula. Yanıttaki defaults bloğu, taşıyıcı seçmeden gönderi
açtığınızda hangi firmanın ve hangi çıkış adresinin kullanılacağını gösterir.
/api/v2/account/transactions
Bakiye hareketleri listesi. Parametreler: type, date_from, date_to, per_page
/api/v2/account/addresses
Kayıtlı çıkış (depo) adresleriniz. Gönderi oluştururken
sender_address_code alanına buradaki code değerlerini yazarsınız.
Yeni depo eklemek için KargoSeç ekibiyle iletişime geçin.
/api/v2/account/webhook
Webhook adresinizi kendiniz tanımlayın. Gövde: url (zorunlu),
rotate_secret (opsiyonel boolean).
{
"success": true,
"data": {
"webhook_url": "https://magazam.com/kargosec/webhook",
"webhook_secret": "aX9...48 karakter",
"signature_header": "X-KargoSec-Signature",
"signature_algorithm": "sha256=HMAC_SHA256(raw_body, webhook_secret)"
}
}
Sır yalnızca bu yanıtta gösterilir, bir daha okunamaz. Güvenli bir yere kaydedin.
Kaybederseniz rotate_secret: true ile yenileyin.
Lokasyonlar
/api/v2/locations/provinces
Türkiye'deki tüm illeri listele
/api/v2/locations/districts/{province_id}
Belirtilen ile ait ilçeleri listele
/api/v2/cargo-companies
Aktif kargo firmalarını listele
Fiyat Hesaplama
/api/v2/prices/compare
Tüm kargo firmalarından fiyat karşılaştırması yap (hesabınızın indirim oranı uygulanmış fiyatlar döner)
{
"shipment_type": "koli",
"from_province_id": 34,
"from_district_id": 450,
"to_province_id": 6,
"to_district_id": 780,
"weight": 5,
"width": 30,
"length": 40,
"height": 20
}
Parametreler
| Alan | Kural | Açıklama |
|---|---|---|
| shipment_type | zorunlu · palet|koli|dosya | Gönderi tipi |
| from_province_id | zorunlu · integer | Çıkış ili ID |
| from_district_id | zorunlu · integer | Çıkış ilçesi ID |
| to_province_id | zorunlu · integer | Varış ili ID |
| to_district_id | zorunlu · integer | Varış ilçesi ID |
| weight | opsiyonel · numeric, min 0.1 | Ağırlık (kg) |
| width | opsiyonel · numeric, min 1 | En (cm) |
| length | opsiyonel · numeric, min 1 | Boy (cm) |
| height | opsiyonel · numeric, min 1 | Yükseklik (cm) |
| desi | opsiyonel · numeric, min 0 | Ölçü vermek yerine doğrudan desi bildirimi |
| preset_desi_range | opsiyonel · 0-5|5-10|10-20|20-30 | Hazır desi aralığı |
| pallet_size | opsiyonel · string | Palet ölçüsü (palet gönderilerde; varsayılan all) |
| weight_range | opsiyonel · string | Palet ağırlık bandı (varsayılan 0-600) |
| pallet_quantity | opsiyonel · integer, min 1 | Palet adedi (varsayılan 1) |
Ölçü (width/length/height), desi ve preset_desi_range alanlarının
hiçbiri gönderilmezse fiyat hesaplanamaz. Yanıttaki her sonuçta
original_price, discount_rate, discount_amount ve indirim uygulanmış
total_price bulunur.
/api/v2/prices/calculate
Belirli bir kargo firması için fiyat hesapla. compare ile aynı alanları alır; ek olarak
cargo_company_id (zorunlu) ve quantity (opsiyonel, integer, min 1) kabul eder.
preset_desi_range bu uçta kullanılmaz. Firma için fiyat bulunamazsa
404 döner.
Gönderiler
/api/v2/shipments
Gönderi oluştur + ücreti tahsil et + etiketi döndür. Ayrıntılı anlatım için Tek Tuş Etiket bölümüne bakın. Aşağıdaki örnek tüm alanların açıkça verildiği hâldir; pratikte gönderici ve taşıyıcı alanlarını göndermenize gerek yoktur.
{
"order_reference": "SIP-2026-10428",
"cargo_company_id": 1,
"shipment_type": "koli",
"sender_name": "Ali Veli",
"sender_phone": "05551234567",
"sender_address": "Atatürk Cad. No:1",
"sender_province_id": 34,
"sender_district_id": 450,
"receiver_name": "Ayşe Fatma",
"receiver_phone": "05559876543",
"receiver_address": "İstiklal Cad. No:2",
"receiver_province_id": 6,
"receiver_district_id": 780,
"weight": 5,
"width": 30,
"length": 40,
"height": 20,
"quantity": 1,
"content_description": "Elektronik parçalar"
}
Kısayol alanları
order_reference— kendi sipariş numaranız. Mükerrer gönderiyi engeller. Tavsiye edilir.receiver_province/receiver_district— ID yerine ad (veya il için plaka kodu).carrier—cargo_company_idyerine"hepsijet","ups", firma slug'ı ya da"cheapest"/"fastest".sender_address_code— birden fazla deponuz varsa hangisinden çıkacağı.wait_for_label—falsegönderirseniz yanıt etiketi beklemez, daha hızlı döner.
Doğrulama kuralları
| Alan | Kural | Açıklama |
|---|---|---|
| order_reference | opsiyonel · string, max 120 | Kendi sipariş numaranız. Mükerrer gönderiyi ve çift tahsilatı engeller — tavsiye edilir. Idempotency-Key başlığı da aynı işi görür. |
| carrier | opsiyonel · string, max 60 | Taşıyıcı: hepsijet, ups, firma slug'ı ya da cheapest/fastest. Verilmezse hesabınızın varsayılanı. |
| cargo_company_id | opsiyonel · geçerli firma ID | carrier yerine ID ile seçim (eski sözleşme) |
| shipment_type | opsiyonel · dosya|koli|palet | Varsayılan koli |
| sender_address_code | opsiyonel · string, max 40 | Kayıtlı çıkış deponuzun kodu. Verilmezse varsayılan depo kullanılır. |
| sender_name | opsiyonel* · string, max 255 | Gönderici adı. Gönderilmezse kayıtlı depodan doldurulur. |
| sender_phone | opsiyonel* · string, max 20 | Gönderici telefonu |
| sender_email | opsiyonel · e-posta, max 255 | Gönderici e-postası |
| sender_address | opsiyonel* · string | Açık adres |
| sender_province / _province_id | opsiyonel* · ad, plaka ya da ID | Çıkış ili |
| sender_district / _district_id | opsiyonel* · ad ya da ID | Çıkış ilçesi |
| receiver_name | zorunlu · string, max 255 | Alıcı adı |
| receiver_phone | zorunlu · string, max 20 | Alıcı telefonu |
| receiver_email | opsiyonel · e-posta, max 255 | Alıcı e-postası |
| receiver_address | zorunlu · string, max 1000 | Açık adres |
| receiver_province / _province_id | zorunlu · ad, plaka ya da ID | Varış ili — "Ankara" gibi ad yeterli |
| receiver_district / _district_id | zorunlu · ad ya da ID | Varış ilçesi — "Çankaya" gibi ad yeterli |
| weight | opsiyonel · numeric, max 2000 | Ağırlık (kg). Verilmezse ücrete esas desi (hacimsel ağırlık) kullanılır ve yanıtta warnings ile bildirilir. |
| width | opsiyonel · numeric, min 0 | En (cm) — ölçü kapısına bakın |
| length | opsiyonel · numeric, min 0 | Boy (cm) — ölçü kapısına bakın |
| height | opsiyonel · numeric, min 0 | Yükseklik (cm) — ölçü kapısına bakın |
| desi | opsiyonel · numeric, min 0 | Ölçü vermek yerine doğrudan desi bildirimi |
| quantity | opsiyonel · integer, 1-200 | Koli adedi (varsayılan 1) |
| content_description | opsiyonel · string, max 500 | İçerik açıklaması |
| wait_for_label | opsiyonel · boolean | Varsayılan true: etiket aynı yanıtta döner. false verilirse yanıt beklemez. |
* Gönderici alanları ya hiç gönderilmez (kayıtlı depo kullanılır)
ya da tamamı birlikte gönderilir. Yarım gönderici
("adı ben verdim, adresi sen tamamla") 422 ile reddedilir; aksi halde etikete
birbirine ait olmayan ad ve adres basılır.
Ölçü kapısı (zorunlu)
- En/boy/yükseklik ya da desi verilmeden koli gönderisi açılamaz; ikisi de yoksa istek
422ile reddedilir. - Beyan ettiğiniz desi, ölçülerden hesaplanan hacimsel desinin altındaysa hacimsel desiye yükseltilir ve kayda ücrete esas desi yazılır. Fiyat da bu desi üzerinden hesaplanır.
- Yanıttaki
dimensions.desiücrete esas desidir;dimensions.desi_sourcebu değerin nereden geldiğini söyler (volumetric,declared,marketplace,default). - Üst sınırlar: tek koli en fazla 1000 desi, tek kenar en fazla 300 cm, tek koli en fazla 1000 kg. Aşan istek
422alır. - Neden: taşıyıcı gönderiyi teslim alırken yeniden ölçer ve gerçek desi üzerinden fatura keser. Düşük beyan, sonradan ölçü farkı borcuna dönüşür.
Örnek yanıt (201 Created)
{
"success": true,
"message": "Gönderi oluşturuldu ve ödemesi alındı.",
"duplicate": false,
"data": {
"id": 123,
"order_reference": "SIP-2026-10428",
"tracking_number": "KS80000123",
"status": "confirmed",
"cargo_company": { "id": 1, "name": "..." },
"carrier": { "id": 1, "name": "...", "tracking_number": "KGS000000123", "synced": true },
"pricing": { "total_price": 128.75, "discount_amount": 14.30 },
"payment": { "method": "balance", "paid": true, "amount": 128.75, "balance": 1871.25 },
"label": { "status": "ready", "content_type": "application/pdf", "base64": "...", "url": "...", "expires_at": "..." },
"payment_status": "paid",
"payment_method": "api_balance"
}
}
201 — gönderi açıldı ve ödendi ·
200 + "duplicate": true — aynı order_reference daha önce
kullanılmıştı, mevcut gönderi döndürüldü (yeni tahsilat YOK) ·
402 — bakiye yetmedi, payment.payment_url ile kart ödemesi bekleniyor.
label.status: ready (PDF hazır) · pending (taşıyıcı gecikti,
shipment.label_ready webhook'u gelecek) · awaiting_payment (önce ödeme).
Webhook adresiniz tanımlıysa shipment.created olayı POST edilir.
/api/v2/shipments
Gönderileri listele. Filtreler: status, tracking_number, date_from, date_to, per_page
/api/v2/shipments/{id}
Gönderi detayı. Etiket durumunu buradan da okuyabilirsiniz:
label_status (awaiting_payment · pending · ready · unavailable),
label_url (yalnızca ready iken dolu, 24 saat geçerli, oturumsuz),
carrier_tracking_number (kargo firmasının gerçek barkodu; yoksa null) ve
tracking_number_is_carrier. Ayrıntı için yukarıdaki "Etiket kuralı" kutusuna bakın.
{
"success": true,
"data": {
"id": 4821,
"tracking_number": "KGS000004821",
"carrier_tracking_number": "KGS000004821",
"tracking_number_is_carrier": true,
"label_status": "ready",
"label_url": "https://kargosec.com/api/v2/shipments/4821/label-download?expires=...&signature=...",
"payment_status": "paid",
"...": "diğer alanlar değişmedi"
}
}
/api/v2/shipments/{id}/cancel
Gönderiyi iptal et. Bakiyeden ödenmişse ücretin tamamı API bakiyenize iade edilir;
ödenmemiş gönderide iade yapılmaz ve varsa kart ödeme bağlantısı kapatılır.
İsteğe bağlı reason alanı gönderebilirsiniz.
İptal kısıtı: Yalnızca gönderi durumu
pending,
confirmed,
payment_pending veya
payment_received iken çalışır.
Diğer tüm durumlarda (alındı, yolda, teslim edildi, iptal edilmiş vb.)
400 Bad Request döner.
Taşıyıcı onayı şarttır: gönderi taşıyıcıya iletilmişse önce onun sisteminde
iptal edilir. Taşıyıcı iptali kabul etmezse
409 Conflict
(carrier_cancel_failed) döner;
gönderi iptal edilmez ve para iade edilmez. Aksi halde kargo taşınmaya devam
ederken siz iade almış olurdunuz.
Örnek yanıt (200 OK)
{
"success": true,
"message": "Gönderi iptal edildi ve bakiyeniz iade edildi.",
"data": {
"refunded_amount": 128.75,
"new_balance": 1871.25
}
}
/api/v2/shipments/{id}/track
Gönderi takip bilgisi
/api/v2/shipments/{id}/label
Kargo etiketini al. Entegrasyonlu taşıyıcılarda (HepsiJet, UPS, Yurtiçi, KolayGelsin, Sürat, PTT)
yalnızca kargo firmasının canlı etiketi döner; canlı etiket alınamıyorsa KargoSeç şablonuna
düşülmez, 409 döner ve hazır olunca shipment.label_ready gönderilir. KargoSeç şablonu yalnızca
entegrasyonsuz (manuel) firmalarda kullanılır.
Örnek yanıt (200 OK)
{
"success": true,
"data": {
"tracking_number": "KS80000123",
"content_type": "application/pdf",
"label_base64": "JVBERi0xLjQKJ...",
"label_url": "https://kargosec.com/api/v2/shipments/123/label-download?expires=...&signature=...",
"label_url_expires_at": "2026-08-12T09:30:00.000000Z"
}
}
label_base64: PDF'in base64 hâli — decode edip doğrudan yazıcıya gönderebilirsiniz, ek istek gerekmez.label_url: imzalı ve 24 saat geçerli bağlantı. API anahtarı gerektirmez; depo yazıcınıza veya personelinize doğrudan verebilirsiniz. Süre dolduğunda bağlantı geçersizleşir.label_url_expires_at: bağlantının geçerlilik bitiş zamanı (ISO 8601).- Ödeme yapılmamış gönderide
400döner. - Etiket henüz hazır değilse (gönderi taşıyıcıya iletilmemişse)
409 Conflictdöner; gönderi taşıyıcıya iletildikten sonra tekrar deneyin.
/api/v2/shipments/{id}/label-download
label_url alanının işaret ettiği uç. PDF'i doğrudan
(Content-Type: application/pdf) döner. Kimlik doğrulaması imza iledir,
X-Api-Key gönderilmez. Bu adresi kendiniz kurgulamayın; her zaman
/label ucundan dönen hazır bağlantıyı kullanın.
Hata Kodları
| Kod | Durum | Açıklama |
|---|---|---|
| 400 | Bad Request | Geçersiz istek — ör. iptale uygun olmayan durumdaki gönderiyi iptal etmek, ödemesiz gönderinin etiketini istemek |
| 401 | Unauthorized | Eksik veya geçersiz API anahtarı |
| 402 | Payment Required | İki farklı sebebi var: (1) API bakiyeniz gönderi ücretini karşılamıyor — yanıtta data.balance ve data.required döner; (2) ödenmemiş ölçü farkı borcunuz var — yanıtta error: "measurement_difference_unpaid", amount ve doğrudan ödeyebileceğiniz payment_url döner. Bakiyeniz borcu karşılıyorsa borç oradan tahsil edilir ve istek normal şekilde devam eder. |
| 403 | Forbidden | Hesap devre dışı ya da istek, hesabınıza tanımlı izinli IP listesi dışındaki bir adresten geldi |
| 404 | Not Found | Kaynak bulunamadı (gönderi size ait değilse de bu kod döner) |
| 409 | Conflict | Etiket henüz hazır değil — gönderi taşıyıcıya iletildikten sonra tekrar deneyin |
| 422 | Validation Error | Doğrulama hatası — ölçü kapısının reddettiği gönderiler de (ölçüsüz/sıfır desi, absürt ölçü) bu kodu döndürür |
| 429 | Too Many Requests | İstek limiti aşıldı (rota katmanı 120/dk veya hesap limitiniz) |
| 500 | Server Error | Sunucu hatası |
Örnek: ödenmemiş ölçü farkı (402)
{
"success": false,
"error": "measurement_difference_unpaid",
"message": "Ödenmemiş ölçü farkınız bulunuyor.",
"amount": 42.50,
"payment_url": "https://kargosec.com/..."
}
Yanıt Formatı
Tüm yanıtlar aşağıdaki yapıdadır:
{
"success": true,
"message": "İşlem başarılı",
"data": { ... },
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 20,
"total": 100
}
}
Webhook'lar
Gönderilerinizin durumunu sürekli sorgulamak yerine, olay gerçekleştiği anda sizin sisteminize
bildirim gönderebiliriz. API müşteri kaydınızdaki webhook_url
alanı doldurulduğunda, aşağıdaki olaylar bu adrese HTTP POST edilir.
Adresin tanımlanmasını isterseniz destek ekibimize iletin.
Olaylar
| Olay | Ne zaman gönderilir |
|---|---|
| shipment.created | API ile yeni bir gönderi oluşturulduğunda |
| shipment.label_ready | Etiket yazdırılmaya hazır olduğunda. Gönderi anında etiketlenemediyse (taşıyıcı gecikmesi) ya da kart ödemesi sonradan tamamlandıysa bu olay gelir. Gövdesinde label_url (24 saat geçerli, imzalı) bulunur. |
| shipment.status_updated | Gönderinin durumu değiştiğinde (taşıyıcıdan gelen otomatik güncellemeler dahil) |
| shipment.cancelled | Gönderi iptal edildiğinde |
API müşterisi webhook'unda olay filtresi yoktur — olayların hepsi aynı adrese gider.
Hangi olayın geldiğini event alanından veya X-KargoSec-Event header'ından ayırt edin.
shipment.label_ready gönderi başına bir kez gönderilir.
Header'lar
| Header | Değer |
|---|---|
| Content-Type | application/json |
| User-Agent | KargoSec-Webhook/1.0 |
| X-KargoSec-Event | Olay adı (ör. shipment.status_updated) |
| X-KargoSec-Signature | sha256=<hmac_sha256(ham gövde, webhook sırrınız)> |
İmza sırrı: PUT /account/webhook
ile adresinizi tanımladığınızda size özel bir webhook_secret
üretilir ve imza onunla atılır. Sır tanımlı değilse imza API anahtarınızla atılır (eski davranış).
Panelden ürettiğiniz ksk_ önekli anahtarlarda
önek imzaya dahil DEĞİLDİR — bu yüzden ayrı bir webhook sırrı tanımlamanız önerilir.
Örnek gövde — shipment.status_updated
{
"event": "shipment.status_updated",
"api_client_id": 12,
"timestamp": "2026-08-11T14:22:05.000000Z",
"shipment_id": 123,
"tracking_number": "KS80000123",
"old_status": "confirmed",
"new_status": "in_transit",
"status_label": "Yolda"
}
shipment.cancelled gövdesi aynı alanları taşır, new_status değeri
cancelled olur. shipment.created gövdesinde ise
old_status/new_status yerine status ve
total_price alanları bulunur.
İmza doğrulama (PHP)
<?php
$rawBody = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_KARGOSEC_SIGNATURE'] ?? '';
$apiKey = getenv('KARGOSEC_API_KEY'); // ksk_...
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $apiKey);
// Zamanlama saldirisina karsi hash_equals kullanin
if (! hash_equals($expected, $signature)) {
http_response_code(401);
exit('Gecersiz imza');
}
$payload = json_decode($rawBody, true);
// ... $payload['event'] degerine gore isinizi yapin ...
http_response_code(200);
echo 'OK';
İmzayı ham gövde üzerinden hesaplayın. JSON'u decode edip yeniden encode ederseniz byte dizilimi değişir ve imza tutmaz.
Yeniden deneme davranışı
- Toplam 3 deneme yapılır (ilk deneme dahil), denemeler arasında yaklaşık 500 ms beklenir.
- Yalnızca geçici hatalar tekrarlanır:
5xx,408,429ve bağlantı hataları. 4xxyanıtları kalıcı hata sayılır (yanlış URL veya imza) ve tekrar denenmez.- İstek zaman aşımı 10 saniyedir. Uzun işleri kuyruğa alıp hemen
2xxdönün. - Aynı olay birden fazla kez ulaşabilir; işleyicinizi idempotent yazın (
shipment_id+new_statusikilisini anahtar olarak kullanabilirsiniz).
Shopify Entegrasyonu
Shopify mağazanız için kod yazmanıza gerek yok. KargoSeç Paneli → Pazaryerleri bölümünden Shopify bağlantısını kurun; siparişleriniz otomatik olarak panele düşer, kargoyu oluşturduğunuzda takip numarası Shopify'a geri yazılır ve müşteriniz bilgilendirilir.
Kurulum adımları
-
1
Shopify yönetim paneline girin
Shopify Admin → Settings → Apps and sales channels
-
2
Uygulama geliştirmeyi açın
Develop apps → Create an app. Uygulamaya bir isim verin (ör. "KargoSeç").
-
3
Yetkileri seçin
Configure Admin API scopes adımında şu iki yetkiyi işaretleyin:
read_ordersvewrite_merchant_managed_fulfillment_orders -
4
Uygulamayı kurun
Install app ile uygulamayı mağazanıza kurun.
-
5
Token'ı kopyalayın
Admin API access token değerini kopyalayın —
shpat_ile başlar. Bu değer yalnızca bir kez gösterilir. -
6
KargoSeç panelinde tanımlayın
Pazaryerleri bölümünde Shopify'ı seçin; mağaza adresinizi (
magazaniz.myshopify.com) ve kopyaladığınız token'ı girip bağlantıyı test edin.
Bilmeniz gerekenler: Yalnızca açık ve kargolanmamış siparişler çekilir;
iptal edilmiş siparişler atlanır. Shopify'da desi kavramı olmadığı için bağlantınızda tanımladığınız
varsayılan desi kullanılır — doğru ayarlayın, aksi hâlde taşıyıcının yeniden ölçümünden
ölçü farkı doğar. Mağaza adresini
magazaniz.myshopify.com biçiminde girin.
Hazır Entegrasyonlar
WooCommerce, Shopify, Trendyol ve 36+ platform için hazır entegrasyon modüllerimizi inceleyin.
Entegrasyon Merkezini Keşfet