REST API v2.0

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. 1

    API anahtarını al

    Panelinizdeki API Anahtarları sayfasından ksk_... anahtarınızı oluşturun.

  2. 2

    İl, ilçe ve firma ID'lerini çek

    GET /locations/provinces, /locations/districts/{province_id} ve /cargo-companies ile gerekli ID'leri alın.

  3. 3

    Fiyatı önizle

    POST /prices/compare ile tüm firmaların indirimli fiyatını karşılaştırın.

  4. 4

    Gönderiyi oluştur ve etiketi al

    POST /shipments tek istekte gönderiyi açar, ücreti bakiyenizden düşer ve yazdırılabilir etiketi aynı yanıtta döndürür.

Büyük desi / paletli mi gönderiyorsunuz? Standart parça kargonun taşımadığı yüksek desili sevkiyatlar için Büyük Desi Kargo Çözümü sayfasından kurumsal talep oluşturun.

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:

  1. Etiketi kendiniz çizmeyin. Yalnızca label.base64, label.url ya da GET /shipments/{id}/label çıktısını yazdırın.
  2. tracking_number her zaman kargo barkodu değildir. Gönderi firmaya basılana dek KargoSeç iç kodudur (KS…) ve ödemeden sonra değişir. Barkod olarak yalnızca carrier_tracking_number kullanın; tracking_number_is_carrier false iken o kodla etiket basmayın, müşteriye barkod diye göstermeyin.
  3. Etiket durumunu label_status ile okuyun (aşağıdaki tablo). Yalnızca ready iken yazdırın.
  4. 402 bir hata değildir. Bakiye yetmediyse gönderi "ödeme bekliyor" açılır; payment.payment_url'yi müşterinize gösterin. Ödeme gelince label_status ready olur ve shipment.label_ready webhook'u gelir.
label_statusAnlamıNe yapmalı
awaiting_paymentÖdeme yokÖdeme bağlantısını gösterin; etiket basmayın.
pendingÖdendi, firmaya iletiliyorBekleyin (webhook gelir) ya da birkaç saniye sonra tekrar sorgulayın. Döngüye girmeyin.
readyEtiket hazırlabel_url'yi açın ya da /label'den PDF alın ve yazdırın.
unavailableGönderi iptalEtiket 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

GET /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.

GET /api/v2/account/transactions

Bakiye hareketleri listesi. Parametreler: type, date_from, date_to, per_page

GET /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.

PUT /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

GET /api/v2/locations/provinces

Türkiye'deki tüm illeri listele

GET /api/v2/locations/districts/{province_id}

Belirtilen ile ait ilçeleri listele

GET /api/v2/cargo-companies

Aktif kargo firmalarını listele

Fiyat Hesaplama

POST /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.

POST /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

POST /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_id yerine "hepsijet", "ups", firma slug'ı ya da "cheapest" / "fastest".
  • sender_address_code — birden fazla deponuz varsa hangisinden çıkacağı.
  • wait_for_label — false gö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 422 ile 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_source bu 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 422 alı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.

GET /api/v2/shipments

Gönderileri listele. Filtreler: status, tracking_number, date_from, date_to, per_page

GET /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"
  }
}
POST /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
  }
}
GET /api/v2/shipments/{id}/track

Gönderi takip bilgisi

GET /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 400 döner.
  • Etiket henüz hazır değilse (gönderi taşıyıcıya iletilmemişse) 409 Conflict döner; gönderi taşıyıcıya iletildikten sonra tekrar deneyin.
GET /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
400Bad RequestGeçersiz istek — ör. iptale uygun olmayan durumdaki gönderiyi iptal etmek, ödemesiz gönderinin etiketini istemek
401UnauthorizedEksik veya geçersiz API anahtarı
402Payment 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.
403ForbiddenHesap devre dışı ya da istek, hesabınıza tanımlı izinli IP listesi dışındaki bir adresten geldi
404Not FoundKaynak bulunamadı (gönderi size ait değilse de bu kod döner)
409ConflictEtiket henüz hazır değil — gönderi taşıyıcıya iletildikten sonra tekrar deneyin
422Validation ErrorDoğ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
429Too Many Requestsİstek limiti aşıldı (rota katmanı 120/dk veya hesap limitiniz)
500Server ErrorSunucu 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, 429 ve bağlantı hataları.
  • 4xx yanı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 2xx dönün.
  • Aynı olay birden fazla kez ulaşabilir; işleyicinizi idempotent yazın (shipment_id + new_status ikilisini 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. 1

    Shopify yönetim paneline girin

    Shopify Admin → Settings → Apps and sales channels

  2. 2

    Uygulama geliştirmeyi açın

    Develop apps → Create an app. Uygulamaya bir isim verin (ör. "KargoSeç").

  3. 3

    Yetkileri seçin

    Configure Admin API scopes adımında şu iki yetkiyi işaretleyin: read_orders ve write_merchant_managed_fulfillment_orders

  4. 4

    Uygulamayı kurun

    Install app ile uygulamayı mağazanıza kurun.

  5. 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. 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