Logistivo CLI: lojistik operasyonunuzu terminalden ve ERP'nizden çalıştırın

Tek bir komut kataloğu üç yüzeyi birden besliyor: lg terminal istemcisi, paneldeki yapay zekâ sohbeti ve dış AI asistanlarının bağlandığı kanal. Bir yetenek bir kez yazılıyor, üçünde birden beliriyor. Bu sayfa bir sözleşmedir. Aşağıdaki komut tablosu elle yazılmadı; her istekte canlı komut defterinden üretiliyor.

Logistivo CLI nedir?

Logistivo CLI (lg), hesabınızdaki yük, talep, teklif, ihracat evrakı, stok, fatura ve gümrük tarifesi işlemlerini terminalden ya da bir betikten çalıştıran komut satırı istemcisidir. Komutlar istemcinin içine gömülü değildir: istemci komut kataloğunu sunucudan çeker ve kendini ona göre çizer. Aynı komutlar istemci kurmadan HTTP ile de çağrılabilir; ERP ve CRM entegrasyonları bu yolu kullanır.

Bugün ne canlı, ne yolda

Bu bölüm bilinçli olarak sayfanın başında duruyor. Bir entegrasyon dokümanının en pahalı hatası, henüz açılmamış bir ucu açılmış gibi anlatmaktır: entegratör kodu yazar, uç 404 döner ve güven bir daha geri gelmez.

Sözleşme donduğu için bugün yazdığınız entegrasyon kodu kalan parçalar açıldıkça çalışmaya devam eder. Bilmediğiniz alanı yok saymak zorundasınız; kırmadan ekleyebilmemizin kuralı budur.

Farkımız: istemci komut bilmez, kataloğu çizer

Bu, sayfanın geri kalanını anlamlı kılan tek karar. Sıradan bir CLI'da komutlar istemcinin içine yazılır; Logistivo'da sunucuda durur.

Klasik kurguda sunucu yeni bir yetenek kazandığında istemcinin de yeni bir sürümü çıkmalı, kullanıcı da onu kurmalıdır. Arada geçen sürede iki taraf farklı şeyler bilir ve bu, entegrasyonların en sessiz kırılma noktasıdır: betik çalışır, çıkış kodu 0 döner, ama komut sunucudaki gerçeği anlatmaz.

Logistivo'da bir komutun tanımı tek bir kayıttır: adı, ne yaptığı, JSON Schema parametreleri, hangi rollerin görebildiği, onay gerektirip gerektirmediği ve geri alınabilir olup olmadığı. lg açıldığında bu kataloğu çeker; yardım metnini, bayrakları ve girdi doğrulamasını ondan üretir. Sunucuya bir komut eklendiği an istemciyi güncellemeden lg onu tanır.

Aynı katalog paneldeki yapay zekâ sohbetini ve dış AI asistanlarının bağlandığı kanalı da besler. Bir yetenek bir kez yazılır, üç yüzeyde birden belirir — ve üçü de aynı rol kapısından, aynı onay kapısından ve aynı denetim defterinden geçer. Ayrı bir CLI komut envanteri yoktur; olsaydı üç yüzey altı ay içinde sessizce ayrışırdı.

Adlandırma kuralı — komut adları nasıl büyür

Katalog büyüyecek. Yeni komutlar rastgele adlandırılmıyor; altı kural uygulanıyor. Bunları burada yayımlıyoruz çünkü entegrasyonunuzun ömrü boyunca yazacağı adlar bunlar ve tahmin edilebilir olmaları sizin işinize yarıyor.

Kurulum ve kimlik

lg, sıfır bağımlılıklı tek dosyalık bir Node betiğidir (Node 18+). Bir müşterinin ERP sunucusuna tek dosya olarak kopyalanabilsin diye böyle yazıldı: npm install gerektiren bir istemci oraya hiç varmaz. İstemci şu anda erken erişimde; dağıtım bağlantısı açıldığında bu bölüme eklenecek. ERP/CRM entegrasyonu için istemciyi beklemeniz gerekmiyor — aynı komutlar HTTP ile çağrılıyor.

1. Oturum açın — lg login e-posta ve parolanızı sorar, dönen erişim jetonunu ~/.logistivo/config.json dosyasına yazar ve kataloğu hemen indirir. Hesabınızda e-posta doğrulaması açıksa kodu da burada sorar — bu adım atlanırsa jeton alınmış ama korunan uçlar hata veriyor olurdu.

2. Sunucu ve CI için: parola değil anahtar — Etkileşimsiz ortamlarda lg login ile parola girilmez. Panelden (Ayarlar › Entegrasyon anahtarları) bir anahtar üretin — isterseniz köprüye adanmış, dar rollü bir ekip üyesi adına — ve LOGISTIVO_TOKEN ortam değişkenine koyun ya da lg login --api-key ile kaydedin. Değişken doluyken yapılandırma dosyası hiç okunmaz. Ayrıntı: "API anahtarı ile bağlanma" bölümü.

3. Kataloğu doğrulayın ve keşfedin — lg commands rolünüzün gördüğü her komutu alanlara göre gruplayıp listeler; lg help o alanın fiillerini, lg help ise tek komutun bütün parametrelerini tipleriyle ve zorunluluk bilgisiyle basar. Bu metinlerin hiçbiri istemcinin içinde yazılı değildir; hepsi katalogdan gelir. Listenin rolünüze göre değiştiğini unutmayın: aynı alanın fiilleri nakliyecide ve müşteride aynı değildir (örneğin loads set-status yalnız nakliyeci kataloğundadır). Bir fiili göremiyorsanız önce rolünüze bakın.

Anahtarı sürüm kontrolüne, CI günlüğüne veya bir sohbet penceresine yazmayın. Entegrasyon anahtarıyla girildiyse lg logout anahtarı sunucuda da iptal eder; parola oturumunda yalnız YEREL kopyayı siler ve bunu açıkça söyler. Denetim defteri argümanlarınızı saklar ama anahtarında token, password, IBAN, kart veya OTP geçen alanları *** olarak maskeler.

İstemci ergonomisi

Aşağıdakiler `lg` istemcisinin gündelik kullanımını kolaylaştıran yeteneklerdir. Hiçbiri HTTP sözleşmesini değiştirmez — doğrudan HTTP ile bağlanıyorsanız bu bölümü atlayabilirsiniz.

API anahtarı ile bağlanma

Bir ERP, CRM veya betik Logistivo'ya panelden üretilmiş bir entegrasyon anahtarıyla bağlanır. Anahtar gerçek bir ekip üyesi adına çalışır: o kişinin rolü neyse komut listesi odur, o kişi ekipten ayrılınca anahtar da kapanır. Sentetik bir "servis hesabı" yoktur ve açılmayacaktır — çok kiracılı izolasyon kullanıcıya bağlıdır, sahipsiz bir köprü ise sessizce yıllarca yazmaya devam eden köprüdür.

1. Panelden anahtar üretin — Ayarlar › Entegrasyon anahtarları › Yeni anahtar. Bir ad verin ("ERP gece senkronu"), kapsamı seçin ve isterseniz süreyi kısaltın. Anahtar yalnız bu ekranda, bir kez gösterilir; sunucu saklamaz. Kaybederseniz Yenile ile yenisini üretirsiniz — eski anında geçersiz olur.

2. Terminalden bağlanın — lg login --api-key ile anahtar doğrulanır, kimlik ve kapsam ekrana yazılır, komut kataloğu indirilir. lg whoami hangi kullanıcı, firma, rol ve kapsamla çalıştığınızı sunucuya sorarak gösterir. lg logout anahtarı sunucuda da iptal eder (parola oturumundaki lg logout bunu yapamaz).

3. Ya da doğrudan HTTP — Anahtar, Authorization: Bearer başlığında taşınan bir erişim jetonudur; aşağıdaki üç komut ucuyla doğrudan kullanılır. Sunucu veya CI ortamında LOGISTIVO_TOKEN değişkenine koyun; değişken doluyken yapılandırma dosyası hiç okunmaz.

Kapsam yalnız komut kataloğunda değil, hesabın TÜM API yüzeyinde zorlanır: yalnız-okuma bir anahtar okuma isteklerini (GET/HEAD/OPTIONS) geçirir, diğer her yazma isteği 403 forbidden döner. İki bilinçli istisna vardır ve ikisi de daha ince bir kapıyla korunur: komut yürütme ucu (kararı komutun read_only bayrağı verir, çünkü yazmayan komutlar da POST ile çağrılır) ve anahtarın kendini iptal etmesi (lg logout, yalnız-okuma anahtarında da serbest). Yine de anahtarı ihtiyacınız olan en dar yetkili üye adına üretin: kapsam neyi yazabileceğinizi sınırlar, hangi kayıtları görebileceğinizi rol belirler.

İlk on dakika: panelden ilk çağrıya

Bir entegrasyonun en pahalı dakikaları ilk on dakikadır. Aşağıdaki dört adım o yolu sırayla kurar; panelde aynı sıra bir sihirbaz olarak da vardır (Ayarlar › Entegrasyon › Kurulum sihirbazı) ve sihirbaz burada anlatılan uçların birebir aynısını çağırır. Sihirbaza erişimi olmayan bir geliştirici bu bölümü okuyarak aynı yere varır.

Dört adımın hiçbiri "gönderdim" ile bitmez. Anahtar gerçekten çalışıyor mu sorusunun cevabı istek defterinde, webhook gerçekten ulaşıyor mu sorusunun cevabı teslimat defterindedir; ikisi de panelde ve lg'de açıktır. Ölçülmeyen bir kurulum, çalıştığı sanılan kurulumdur.

Kum havuzu: yazmayı canlıya dokunmadan deneyin

Ön uçuş (dry_run) bir komutun ne YAPACAĞINI söyler; ama idempotency'nin gerçekten tekrar oynatıp oynatmadığı, webhook'un gerçekten teslim edilip edilmediği, hata dallarının nasıl göründüğü ve kredinin nereden düştüğü ancak GERÇEK bir yazmada görülür. Kum havuzu bunun için var: firmanızın ikizi olan ayrı bir kiracı, aynı kod, aynı komut kataloğu — ama canlı defterinize dokunmayan.

Kum havuzu bir istek bayrağı değil, bir KİRACIDIR. Firmanız için açılan ayrı bir Logistivo firması: kendi kullanıcısı, kendi paketi, kendi kredi defteri, kendi webhook abonelikleri. Ortam anahtarın firmasından TÜRETİLİR, çağıran veremez; yanlış profil seçseniz bile istek sunucuda 403 ENVIRONMENT_MISMATCH ile durur. Bu yüzden "kum havuzuna yazdım sandım, canlıya yazmışım" hatası yapısal olarak mümkün değildir.

Yüzey birebir aynıdır — ölçüldü: kum havuzu anahtarının çizdiği katalog, canlı anahtarın çizdiğinin aynısıdır (bir müşteri anahtarında iki tarafta da 185 komut). Kum havuzunda çalışan bir köprü canlıda da çalışır; öğrendiğiniz hiçbir şeyi ikinci kez öğrenmezsiniz.

Kum havuzu boş açılmaz: içinde üretilmiş (kopyalanmış DEĞİL) tohum veri bulunur — cariler, iki yönlü yükler ve talepler. Adlar açıkça uydurmadır ve e-postalar @sandbox.invalid alanındadır; hiçbir gerçek kiracının satırı okunmaz, klonlanmaz ya da örnek alınmaz.

"Sıfırla" düğmesi bilerek YOKTUR ve hiçbir kayıt, dosya ya da evrak silinmez. Temiz bir başlangıç istiyorsanız yenileme yeni bir nesil açar, eskisi emekli olarak durur. Birikmiş birkaç yüz prova satırının maliyeti, yanlış kiracıya bağlanmış bir silme rutininin maliyetinin yanında sıfırdır.

Komut modeli

Tek bir gramer var ve istisnası yok. Bir komutu nasıl çağıracağınızı bilmek için tek gereken, kataloğun o komut için ne dediğidir.

lg loads list --status=in_transport --limit=20 --json

Bayrak adları şema adlarıdır ve alt çizgi taşıyabilir (--load_code, --amount_per_vehicle). Bu kasıtlı: bayrağı görünce hangi JSON alanına gittiğini bilirsiniz ve HTTP'ye geçtiğinizde hiçbir ad çevirisi yapmanız gerekmez. Evet/hayır tipindeki bir parametre değersiz yazıldığında true olur (--only_open); tersi --no-only_open ile verilir. Değeri tire ile başlayan bir argümanı --bayrak=değer biçiminde yazın, aksi halde unutulmuş bir bayrak bir sonrakini sessizce değer diye yutar.

Gerçek örnekler

Aşağıdaki komutların hepsi katalogda bugün var olan komutlardır; adlar ve parametreler uydurulmadı. Çıktılar kısaltılmıştır. Çıktılar `data.result` düzeyini gösterir; HTTP'de aynı nesne `{success, data:{…}}` zarfının içinden gelir (bkz. HTTP komut API'si).

İstemci olmadan: HTTP komut API'si

lg bir kolaylıktır, kapı değil. Katalog ve yürütme aynı üç HTTP ucundan geçer; bir ERP veya CRM entegrasyonu doğrudan buraya bağlanır. Kimlik, Authorization: Bearer ile taşınan kişisel erişim token'ıdır. HER yanıt aynı zarfla döner: `{ "success": bool, "data": { … }, "code": "…", "message": { … } }`. Sözleşmenin tamamı `data` içindedir — `contract_version`, `command`, `status` ve komut çıktısı olarak `result`; hata durumunda `error_code`, `error_key` ve `error`. Bu sayfadaki yanıt örnekleri yerden kazanmak için `data` nesnesini gösterir, zarfı değil; kendi kodunuzda `data`'yı açmayı unutmayın. `lg --json` de zarfın TAMAMINI basar, dolayısıyla jq yolları `.data.result…` ile başlar. Tek istisna `/api/public/status`: nöbetçi araçlar ayrıştırmadan alarm kurabilsin diye o uç zarfsızdır.

Onayı 200 + ok:false ile istemek yasaktır ve hiçbir zaman yapılmayacaktır. Sebep basit: istemciler 200'ü başarı sayar; onay isteği 200 ile dönseydi akış sessizce ölür, kimse fark etmezdi. Onay daima 409'dur.

Onay kapısı ve geri alınamaz komutlar

Katalogdaki her komut iki bayrak taşır: confirmation_needed (çalışmadan önce açık onay ister mi) ve irreversible (yaptığı iş geri alınabilir mi). İkisi ayrı sorulardır ve ikisi de sunucuda zorlanır — istemcinin kibarlığına bırakılmaz.

Kapı, iş kuralının değil sorumluluğun kapısıdır. Bir teklif vermek navlun sözleşmesine giden ilk adımdır; bir fatura kesmek muhasebe kaydı doğurur; bir stok hareketi defteri değiştirir. Bunların hiçbiri "yanlışlıkla iki kez çalıştırılabilir" olmamalıdır.

Kapı bir komutun ETKİN halinden okunur. Bir komut başka bir komutu sarmalıyorsa (sohbetteki genel yürütücü gibi) kapı sarmalayanın değil, gerçekten koşacak olanın bayrağından gelir. Sabit bir bayrak kullanılsaydı iki hatadan biri kaçınılmazdı: ya fatura komutu onaysız koşardı, ya her ülke araması onay kartı çıkarırdı.

read_only ile kapısızlık aynı şey değildir. Üç ayrı durum vardır: invoices preview hem kapısızdır hem yazmaz; loads create hem kapılıdır hem yazar; invoices create kapısızdır ama yazar — ortada bir taslak oluşur. Ölçüt tek: komut döndüğünde veritabanında bir satır değişti mi?

Bir entegrasyonun onay kapısını her çağrıda otomatik geçmesi teknik olarak mümkündür ama tavsiye edilmez. Doğru desen, kapıyı yalnız gerçekten geri alınabilir olduğunu bildiğiniz komutlarda otomatikleştirmek; geri alınamazları bir insanın kuyruğuna düşürmektir.

Ön uçuş: yazan komutu çalıştırmadan etkisini görmek

Bir ERP köprüsünü ilk kez bağlarken en pahalı adım, gövdenin doğru olup olmadığını öğrenmek için komutu GERÇEKTEN çalıştırmaktır: canlı defterde taslak fatura, yanmış kredi, elle temizlik. dry_run bunu bitirir — istek gövdesine bir alan eklersiniz, komut çalışmaz, ne olacağını okursunuz.

Bugün defterde 207 komut var; 105 tanesi okuma yapar ve bir şey yazmaz. Geriye kalan 102 yazan komuttan 85 tanesi onay kapılıdır: confirm olmadan çağrıldıklarında zaten 409 ile ne yapacaklarını anlatırlar. Sorun kalan 17 kapısız komuttaydı — fatura taslağı, ihracat belgesi taslağı, kalem ekleme gibi bir köprünün ilk bağladığı zincir. Onlarda çağırmak yapmaktı.

İkinci boşluk kapılı komutlarda bile vardı: şema doğrulaması onay kapısından SONRA koşuyor. Yani eksik argümanlı bir çağrı önce onay kartını alıyor, onaylıyor ve ancak ondan sonra "şu alan eksik" duyuyordu. Ön uçuş her iki cevabı tek turda verir.

En sık ve en geç fark edilen köprü hatası ise şudur: şemada olmayan bir alan gönderilir (customer_id yerine recipient_contact_id beklenir), sunucu o alanı sessizce atar, komut 200 döner ve kayıt yanlış yere yazılır. Ön uçuş yanıtı bu alanları arguments.ignored altında adıyla listeler; hiçbir hata mesajı bunu söylemez.

Ön uçuş hiçbir şey yazmaz ve bu bir vaat değil, ölçüm: yazan komutların TAMAMI (iki ayrı argüman kümesi ve iki ayrı rolle, 178 ön uçuş) çalıştırılırken üretilen her SQL ifadesi dinlendi. Tek bir INSERT/UPDATE/DELETE, kuyruğa atılmış tek bir iş, gönderilmiş tek bir e-posta yok; 31 tablonun satır sayısı ve kredi bakiyesi değişmedi.

Çıkış kodu gerçek çağrının alacağı kodun aynısıdır — çalışırdı 0, onay kapısı 4, idempotency çakışması 2, diğer 1 — yani CI adımınızda "lg … --dry-run || exit" anlamlı bir kapıdır.

Idempotency: tekrar denemek neden çift kayıt üretmez

Bir ERP hata mesajını okumaz, ekranı görmez ve zaman aşımından sonra aynı isteği tekrar gönderir. Bu bölüm tam olarak o davranış için var.

idempotency_key verilen bir çağrı en fazla bir kez koşar. İkinci çağrı komutu yeniden çalıştırmaz; defterdeki sonucu döndürür ve durumu replayed olur. Ağ koptuğunda, zaman aşımı yaşandığında ya da kuyruk aynı işi iki kez ele aldığında mükerrer fatura yerine ilk sonucu alırsınız.

Anahtar yazan her komutta kullanılmalıdır. Kataloğun read_only alanı bu ayrımı size bedavaya verir: read_only: false olan her komut idempotency anahtarı hak eder.

Tekrar stratejiniz üstel geri çekilme kullanmalı ve her denemede AYNI anahtarı taşımalıdır. Deneme başına yeni anahtar üretmek idempotency hiç kullanmamakla aynıdır. Aynı anahtarı paralel göndermeyin: en-fazla-bir-kez ardışık tekrarlar için garantidir, birbiriyle yarışan iki istek için değil.

Artımlı senkron ve sayfalama

Bir ERP/CRM köprüsü “her saat her şeyi yeniden çekmek” yerine değişenleri çeker. Liste komutlarının tamamı — loads list, demands list-own, contacts list, invoices list, teammates list, load-groups list, reservations list, drivers list, tenders list, products search, warehouses search — iki ortak parametre alır ve bir ortak alan döndürür.

Neden offset yok: canlı bir tabloda ofset kayar. İki sayfa arasında eklenen bir kayıt bir satırı atlatır ya da iki kez saydırır ve bunu kimse fark etmez. İmleç ileri yönlü olduğu için araya giren ya da güncellenen kayıt listenin sonuna düşer: hiçbir satır kaybolmaz, hiçbir satır ikilenmez.

Tam ilk çekim de aynı mekanizmadır: updated_since=1970-01-01T00:00:00Z ile başlayın ve next_cursor null olana kadar izleyin. Ayrı bir “dışa aktarım” ucu yoktur çünkü gerekmez.

lg ile aynı şey: lg loads list --updated_since=2026-09-01T00:00:00Z --limit=100 --json, sonra lg loads list --cursor= --json.

Bir sonraki senkron için updated_since değerini gördüğünüz en büyük updated_at yapın. Zaman damgası saniye hassasiyetlidir; saniye sınırındaki bir kayıt iki kez gelebilir — kendi tarafınızda external_ref ya da kodla upsert yaptığınız sürece zararsızdır. updated_since ya da cursor vermezseniz komut sohbet kipinde çalışır: insan sıralaması, en fazla 20 satır, next_cursor null ve truncated “daha var” der. Senkron için o kipi kullanmayın.

Bu bölümün makine okunur hata anahtarları: INVALID_CURSOR, INVALID_UPDATED_SINCE, DUPLICATE_EXTERNAL_REF, EXTERNAL_REF_TOO_LONG, EXTERNAL_REF_INVALID. Hepsi HTTP 422 döner; gövdede error_code: "failed" ve result.error_key bulunur. Metne değil, anahtara dallanın.

Kendi anahtarınız: external_ref

Artan kayıt numaralarını (invoice_id, contact_id) ERP'nizde iş anahtarı yapmayın; onlar opak ve firmanıza kapalıdır. Yük, talep, cari, fatura, ürün ve depo kayıtları sizin anahtarınızı taşır.

Giden webhook: olay olduğunda size POST atarız

Buraya kadar her şey çekmeydi: siz sorarsınız, biz cevaplarız. Bir ERP köprüsünün "yük durumu değişti", "fatura kesildi", "teklif geldi" olaylarını öğrenmek için dakikada bir sorması gerekiyordu. Artık gerekmiyor: bir https adresi kaydedersiniz, ilgilendiğiniz olayları seçersiniz, olay olduğunda o adrese imzalı bir POST gelir.

Push, pull'un YERİNE değil YANINA kondu. Artımlı senkron (updated_since + imleç) olduğu gibi duruyor ve hâlâ doğru araç: ilk dolum, geçmişi toparlama ve "kaçırdım mı" sorusunun cevabı orada. Webhook ise gecikmeyi dakikalardan saniyelere indirir. Sağlıklı bir köprü ikisini birden kullanır — webhook'u tetikleyici, senkronu güvenlik ağı olarak.

Gövde bir SİNYALDİR, veri kopyası değil. Künye gider (kimlik, iş anahtarınız external_ref, durum, zaman); ayrıntıyı kendi anahtarınızla GET ile çekersiniz ve o çağrı zaten kendi yetki kapılarınızdan geçer. Böylece sızıntı yüzeyi künyeyle sınırlı kalır. İki alan bilinçli olarak gövdede YOKTUR: teklifi veren firmanın kimliği (gizli teklifler panelde takma adla görünür; kimliği webhook'a koymak o gizliliği ikinci bir kanaldan delerdi) ve rezervasyon iletişim bilgileri (kişisel veriyi gereksiz bir kanaldan dışarı taşımamak).

Olay adları DONDURULMUŞTUR. Bir adın anlamı değişirse yeni ad açılır, eskisi kullanımdan kaldırma penceresiyle yaşar. Gövdeye yeni alan eklemek sözleşme sürümünü ARTIRMAZ — tüketici bilmediği alanı yok saymak zorundadır.

Olay kataloğu

Aşağıdaki 13 olayın her birinin arkasında GERÇEKTEN yayılan bir olay sınıfı vardır. Katalogda "olsa güzel olurdu" diye bir ad yoktur: ilan edilmiş ama hiç tetiklenmeyen bir olay, entegratörün sonsuza kadar beklediği bir olaydır ve arızası sessizdir. Bu tablo da elle yazılmadı — sayfa her açıldığında canlı katalogdan çizilir.

invoice.payment_recorded bilinçli olarak YOKTUR: o olay sınıfı kodda duruyor ama hiçbir yerden yayılmıyor. Tahsilat olayı, sınıf gerçekten yayılmaya başladığı gün eklenecek — daha önce değil. Bir olayı erken ilan etmek, onu hiç eklememekten kötüdür.

İmza doğrulama

Her istek X-Logistivo-Signature başlığı taşır: t=,v1=. İmzalanan dize "." ve algoritma HMAC-SHA256'dır. v1 öneki şemayı sürümlenebilir tutar: yarın ikinci bir şema gelirse başlık t=…,v1=…,v2=… taşır ve siz bildiğinizi seçersiniz.

Node ve saf PHP için, bağımlılığı olmayan iki referans alıcı yayınlıyoruz. İkisi de yukarıdaki dört kuralı uygular ve --selftest ile kendini sınar: geçerli imza, kurcalanmış gövde, yanlış gizli değer, pencere dışı damga, bozuk başlık, yeniden serileştirme tuzağı ve iki tür tekrar (aynı teslimat / aynı olgu). Doğrulayıcı bizim de kullandığımız kodun birebir karşılığıdır — yayınladığımız sözleşmeyi kendi testimizde de tüketiyoruz.

Teslimat, tekrar ve susturma

Alıcınız her zaman ayakta olmayacak. Ray bunu varsayar: geçici arıza tekrar takvimine girer, kalıcı arıza aboneliği susturur ve susturmanın SEBEBİ daima yazılır.

Susturma sebebi makine okunur ve kararlıdır (delivery_failures, endpoint_gone, unsafe_target, key_revoked, by_user) ve hem panelde hem `lg webhooks list` çıktısında görünür. Sebepsiz susturma, "neden gelmiyor" sorusunu cevaplanamaz bırakırdı. Yeniden açmak sayacı ve damgayı sıfırlar.

Adresi siz yazarsınız, isteği BİZİM sunucumuz yapar. Kapı olmasaydı, bir bulut meta-veri adresi yazan kiracı ağımızın içinden istek attırabilirdi. Bu yüzden adres hem kayıt anında hem HER teslimatta denetlenir:

Sağlık ve durum: köprü sustuğunda bunu sizden önce kimse fark etmesin

Bir entegrasyon köprüsü nadiren gürültüyle ölür. Genellikle sabaha karşı sessizce susar: jetonun süresi dolar, anahtarın adına çalıştığı kişi ekipten çıkarılır, bir kapsam daraltılır ya da alıcı adresi 403 dönmeye başlar. Sonucu ilk fark eden neredeyse her zaman müşteridir. lg status bu sırayı tersine çevirmek için var.

Tek komut iki soruyu birden cevaplar, çünkü bir kesinti anında ikisi de aynı anda sorulur: platform ayakta mı, ve benim köprüm sağlıklı mı. Platform satırı jetonsuz da çalışır — bir arıza anında ilk şüpheli jetonun kendisidir ve durum sorusunu jetona bağlamak, tam ihtiyaç duyduğunuz anda sizi cevapsız bırakırdı.

Sağlık özeti yeni bir defter tutmaz; zaten var olan üç kaynağı tek cümlede toplar: günlük kullanım sayacı (ne kadar çağırdınız, ne kadarı hataydı), istek defteri (hangi istek, ne zaman, neden reddedildi) ve giden webhook teslimat defteri (olay alıcıya ulaştı mı). Hata oranı daima günlük sayaçtan okunur; ayrıntı defteri tavanlıdır ve tavana dayandığında bunu açıkça söyler.

Aynı sağlık özeti panelde de görünür: Ayarlar › Entegrasyon › Anahtarlar ekranında her satırın yanında bir rozet ve altında gerekçesi durur. Eşikler istemcide hesaplanmaz; sunucu neyi hangi seviyeye koyduysa panel de lg status de onu boyar, böylece iki ekran aynı anahtar için hiçbir zaman farklı bir şey söyleyemez.

Nöbetçi izleyiciniz için jeton gerekmez. Uç yalnız durum kelimeleri döner; sürüm, sunucu adı, kuyruk adı, iş sayısı, hata metni ya da herhangi bir müşteri verisi taşımaz ve taşıyamaz.

Sağlık özeti, her satır için sabit sayıda sorguyla üretilir; anahtar sayısı arttıkça sorgu sayısı artmaz. Ayrıntı için lg logs ile o anahtarın son isteklerini, lg webhooks list ile giden köprünün durumunu okuyabilirsiniz.

Hata ve çıkış kodları

Makinenin dallanacağı şey kararlı bir dizedir. error alanındaki metin insanı hedefler, yerelleştirilir ve haber verilmeden değişir — mesaj metnine göre dallanan entegrasyon desteklenmez ve kırıldığında bu bir hata sayılmaz.

İki taksonomi, iki alan. error_code taşıma katmanıdır (yukarıdaki tablo) ve önce ona dallanırsınız. error_key ise failed içindeki kararlı iş kuralı anahtarıdır — INSUFFICIENT_CREDITS, NOT_FOUND, DUPLICATE_CONTACT, INSUFFICIENT_STOCK — katalogda (error_keys) ve aşağıda sözlük olarak yayınlanır. Henüz anahtar üretmeyen komut error_key: null döndürür; sözlükte olmayan bir anahtarı genel bir hata sayın.

Kararlılık sözü

Bir entegrasyon sözleşmesinin en pahalı sorusu şudur: “yazdığım kod yarın da çalışacak mı?” Cevabı tek bir sayı verir — katalogdaki contract_version ve her yanıtta gelen X-Contract-Version başlığı. O sayı tek bir soruyu cevaplar: daha önce yazdığın kod, hiç değiştirmeden çalışmaya devam eder mi? Artmadıysa evet. Arttıysa hayır — dayandığın bir şey kaldırıldı ya da daraltıldı.

Çünkü ilan hiçbir şeyi kaldırmaz: ilan gününden sonra da eski kodun aynen çalışır. Sürümü ilanda artırmak tek bir değişiklik için iki sinyal üretir ve seni ilkini yok saymaya alıştırırdı — yani asıl sinyali zayıflatırdı. İlan zaten senin yaptığın çağrının üstünden geliyor: katalog satırında deprecated_at ve replaced_by, o komutun yanıtında X-Deprecated başlığı ve gövdede deprecated bloğu, lg kullanıyorsan stderr'e tek satır uyarı. Yani “kalkıyor” bilgisini öğrenmek için hiçbir şey yapman gerekmez; log'unda zaten duruyor.

İlan ile kaldırma arasında en az iki takvim çeyreği vardır. Pencere boyunca eski komut yanıt vermeye devam eder ve her çağrıda uyarır. Bir CLI adı emekliye ayrıldığında yerine geçen komut o adı alias olarak devralır: pencere boyunca eski ad eski komuta gider, komut kaldırıldığı gün aynı çağrı yenisine düşer — senin istemci sürümü çıkarman gerekmeden.

preview_invoice → get_invoice (ilan 3 Eylül 2026). get_invoice aynı önizleme bloğunu döndürür, üstüne kalemleri, vergi kırılımını, kayıtlı tahsilatları, kalan bakiyeyi ve kendi ERP anahtarınla (external_ref) adresleme imkânını ekler. preview_invoice çalışmaya devam ediyor; lg invoices preview de öyle — ikisi de uyarı basıyor.

Komut kimlik tablosu

Aşağıdaki tablo elle yazılmadı: sayfa her açıldığında canlı komut defterinden üretiliyor. Sunucuya bir komut eklendiğinde burada kendiliğinden beliriyor. "Kapı" sütunu bir komutun onay isteyip istemediğini ve geri alınabilir olup olmadığını gösterir; "Roller" sütunu ise onu hangi hesap tiplerinin katalogunda göreceğini.

API adı (list_loads) dondurulmuştur ve değişmez; HTTP çağrılarında kullanacağınız ad odur. CLI kimliği (loads list) sürüm politikasına tabidir: ilan edildikten sonra ancak sürüm artışı ve geçiş penceresiyle değişir, geçiş boyunca eski çift katalogda alias olarak sunulur. Buradaki açıklamalar komutun kendi künyesinden gelir ve kısaltılmıştır — tam metin, parametre tipleri ve enum değerleri için katalog ucuna bakın ya da lg help çalıştırın. Künye metinleri İngilizcedir: kataloğu asıl tüketen taraf bir istemci ya da bir dil modelidir, ve o metni çevirmek tek kaynağı ikiye bölerdi.

ERP ve CRM entegrasyonu — Kimlik: servis hesabı yok, gerçek kullanıcı var

Bir ERP veya CRM, Logistivo'ya panelden çıkarılmış kişisel erişim token'ına sahip gerçek bir firma kullanıcısıyla bağlanır. Sentetik bir servis hesabı — firmasız, kapsam muafiyetli, kimsenin sorumlu olmadığı bir asli kimlik — açılmaz.

Bu bir tercih değil mimaridir. Çok kiracılı izolasyonun tamamı kullanıcının firmasına dayanır; firması olmayan bir kimlik için izolasyon kapsamı işlevsiz kalır ve o token tek bir yanlış sorguda kendisine ait olmayan veriyi görür. İkinci gerekçe denetimdir: defterdeki kullanıcı alanı "bunu kim çalıştırdı" sorusunu bir insana bağlar; servis hesabı bu alanı anlamsızlaştırır ve fatura kesen entegrasyonun sorumlusu kalmaz. Üçüncüsü iptaldir: token bir kişiye aitse, o kişi ayrıldığında entegrasyon da susar. Sahipsiz köprü, sessizce yıllarca yazmaya devam eden köprüdür.

ERP ve CRM entegrasyonu — Sürümleme ve deprecate

Katalog yanıtı bir contract_version tamsayısı taşır; komut satırları since, deprecated_at ve replaced_by alanlarını taşır. Sözleşme sürümü yalnız kırıcı değişikliklerde artar.

ERP ve CRM entegrasyonu — Kararlı tanımlayıcılar: artan id'yi ERP'ye anahtar diye vermeyin

Dahili artan id'ler opaktır ve kiracıya kapalıdır: başka bir firmanın geçerli id'si size veri değil "bulunamadı" döndürür. Ama opak olmaları onları iş anahtarı yapmaz. ERP'nin kendi kaydında saklayacağı şey bir iş anahtarı olmalıdır.

ERP ve CRM entegrasyonu — Sayfalama, filtreleme ve artımlı senkron

Liste komutları limit alır ve count döner. Gece senkronu için sözleşme aşağıdakini taahhüt eder; bunu benimseyen bir liste komutu JSON Schema'sında cursor ve updated_since ilan eder, edene kadar onu küçük bir pencere sayın (tavan 20 satır, imleç yok).

ERP ve CRM entegrasyonu — Hız sınırları

Sınır anahtarı jetondur, IP değil: bir ERP tek NAT arkasından gelir, IP tabanlı sınır tüm firmayı tek kullanıcı sayardı. İki anahtarlı iki entegrasyon birbirinin kotasını asla yemez — "anahtar başına bir entegrasyon" kuralının ikinci gerekçesi.

ERP ve CRM entegrasyonu — Yapılmayacaklar

Bir sözleşmenin en yararlı kısmı çoğu zaman budur: neyin gelmeyeceğini bilmek, mimarinizi ona göre kurmanızı sağlar.

Makine okunur katalog

Bu sayfa insanlar için yazıldı. Bir yapay zekâ asistanı ya da otomatik bir istemci için aynı bilginin kimlik doğrulamasız, yapısal bir kopyası var.

GET /api/public/cli/catalog kimlik doğrulaması istemez ve komutların kamuya açık künyesini döndürür: dondurulmuş API adı, CLI alan/fiil kimliği, açıklama, JSON Schema parametreleri, read_only, confirmation_needed ve irreversible bayrakları. Kişisel veri, kiracı verisi ya da örnek kayıt döndürmez — yalnız yüzeyin ne olduğunu anlatır.

Bir dış ajan için doğru kullanım şudur: kataloğu oku, kullanıcıya hangi işlerin mümkün olduğunu KENDİ kelimelerinle anlat, ve yürütme gerektiğinde kullanıcıyı kendi token'ıyla kendi ortamında çalıştırmaya yönlendir. Ajan, kullanıcının token'ını istemez, üretmez ve taşımaz.

Logistivo'yu bir yapay zekâ asistanına bağlamak (üyelik ve talep açma akışı) ayrı bir kanaldır ve kendi sayfasında anlatılıyor:

Makine okunur tanım: OpenAPI 3.1 ve Postman

Yukarıdaki katalog Logistivo'nun kendi biçimidir. Aynı bilgi, araçlarınızın hiç öğrenmeden okuyabileceği iki endüstri standardı biçimde de yayınlanıyor: bir OpenAPI 3.1 tanımı ve bir Postman koleksiyonu. İkisi de elle yazılmıyor — her istekte canlı komut defterinden üretiliyor, dolayısıyla eskiyemiyorlar.

Tanım kataloğun ta kendisidir, ikinci bir gerçeklik değil. Her komut bir POST /api/common/commands/ operasyonu olarak görünür; gövde şeması komutun kendi JSON Schema'sıdır (asistanın gördüğü şemayla birebir aynı), yanıt şeması ortak zarftır, kapı bayrakları (read_only, confirmation_needed, irreversible ve kredi künyesi) x-logistivo uzantısında, iş hatası anahtarları x-error-keys altında durur. Kullanımdan kalkan bir komut deprecated: true ile işaretlidir ve altı aylık geçiş penceresi boyunca çağrılabilir kalır.

Komut yüzeyinin yanında entegrasyon sözleşmesini taşıyan REST uçları da tanımdadır: artımlı senkron sunan 10 liste ucu (updated_since + cursor + limit) ve kendi anahtarınızı (external_ref) kabul eden 7 yazma ucu. Logistivo'nun REST yüzeyi bundan çok daha geniştir; gerisi tanıma BİLEREK konmadı. O uçların gövdeleri ürünün kendi sözleşmesidir ve tahminle yazılmış bir şema, ürettiğiniz istemciyi ilk çağrıda kırardı — üstelik hatayı bizde değil kendi kodunuzda arardınız.

Tanım isteyenin ROLÜNE göre üretilir: başka bir rolün komutu belgeye girmez, çünkü belge bir sözlük değil bir sözleşmedir ve içindeki her operasyonun o jetonla çağrılabilir olması gerekir. Kimliksiz sürüm üç rolün birleşimidir ve orada her satır hangi rollerin göreceğini x-logistivo.roles altında açıkça söyler.

Bize güvenmeyin, doğrulayın: npx @redocly/cli lint logistivo-openapi.json — tanım sıfır uyarıyla geçer.

Kod üretimi: tanımdan tipli istemci

Tanımı indirdiniz; şimdi ondan çalışan kod üretin. `lg codegen` OpenAPI belgesini okuyup tek dosyalık, bağımlılıksız bir istemci yazar — TypeScript (tip tanımları + ince çağrı sarmalayıcı) ya da PHP (PHPDoc array-shape'li istemci sınıfı). Üretilen dosyada `npm install` yoktur, composer yoktur; TypeScript tarafında `fetch`, PHP tarafında `ext-curl` yeter.

Üretim SİZİN makinenizde olur, bizim sunucumuzda değil. Sebebi tercih değil: tanımı bir kez indirip depoya sabitlerseniz (`lg spec --out=...`) her derlemede aynı komut ağsız ve jetonsuz koşar; CI'ınız bizim ayakta olmamıza bağlanmaz. Üstelik üretilen kod sizin ERP'nizde ÇALIŞAN koddur — onu bir API'den indirmek yerine deponuzda tutmak, her sürümde neyin değiştiğini `git diff`te görmenizi sağlar.

Üretilen istemci Logistivo'nun üç rayını da doğru açar ve bunu tahminle değil belgeden öğrenir: her operasyon `x-logistivo.surface` alanında hangi raya ait olduğunu söyler. Komut rayı `{success, data:{…}}` zarfını açar; REST senkron listesi ZARFSIZ döner ve olduğu gibi verilir (açılsaydı `next_cursor` düşerdi); REST yazma rayı ucun kendi ürün gövdesini döndürür. Genel amaçlı bir kod üreteci bu ayrımı bilmez — bizimki bilir.

Tipler tahmin değil: her komutun argüman arayüzü, asistanın gördüğü JSON Schema'nın ta kendisinden üretilir. Zorunlu alan zorunlu, enum birlik tipi, iç içe nesne iç içe tip olur. Pratik karşılığı şudur: sunucuda zorunlu bir alan varsa onu unutan çağrı CANLIDA 422 almaz, DERLEMEDE durur.

Üretilen dosyaya üretim anı yazılmaz: aynı tanım ve aynı bayraklar aynı baytı verir. Böylece yeniden üretim `git diff`'te gürültü yapmaz ve gerçekten değişen tek şey — sözleşme — görünür kalır.

Dürüst kapsam

Bu bölümü küçültmek yerine büyütüyoruz. Bir entegrasyon sözleşmesinin değeri, vaat ettiklerinden çok neyi vaat etmediğini net söylemesindedir.

Sıkça sorulan sorular

Logistivo CLI ne işe yarar?

Logistivo hesabınızdaki operasyon işlerini — yük listeleme ve okuma, açık talepleri görme, teklif verme, yük durumu ilerletme, sürücü atama, ihracat evrakı hazırlama, stok hareketi, fatura kesme, GTİP ve dampinge karşı vergi sorgusu — terminalden veya bir betikten çalıştırmanızı sağlar. Aynı komutlar ERP/CRM entegrasyonu için HTTP ile de çağrılabilir.

Logistivo CLI'da komutlar nasıl adlandırılır?

Biçim lg --parametre=değer şeklindedir. Alan çoğul bir varlıktır (loads, demands, invoices, export-documents), fiil kapalı bir sözlükten gelir (list, get, create, search, set, issue, generate ve benzerleri). Bir varlığın bütün fiilleri tek alanda toplanır ve (alan, fiil) çifti katalog genelinde benzersizdir.

CLI'a nasıl kimlik doğrularım?

Logistivo panelinden çıkardığınız kişisel erişim token'ıyla. lg login token'ı sorup yerel yapılandırma dosyasına yazar; betik ortamlarında LOGISTIVO_TOKEN ortam değişkenini kullanın. HTTP tarafında token Authorization: Bearer başlığında taşınır.

ERP entegrasyonu için servis hesabı açabilir miyim?

Hayır. Entegrasyon, panelden açılmış gerçek bir firma kullanıcısının token'ıyla bağlanır. Firmasız sentetik bir kimlik çok kiracılı izolasyonu işlevsiz bırakır, denetim defterindeki "kim çalıştırdı" alanını anlamsızlaştırır ve sahibi ayrıldığında susmayan bir köprü bırakır. Doğru desen, entegrasyona adanmış, dar rollü ve sorumlusu belli bir kullanıcı açmaktır.

Logistivo'nun test (sandbox) ortamı var mı?

Var ve self-servistir: firmanız için ayrı bir kum havuzu kiracısı açılır — aynı kod, aynı komut kataloğu, kendi kredi defteri. Ortam anahtarın firmasından türetilir, istekle verilemez; yanlış profille yaptığınız çağrı sunucuda 403 ENVIRONMENT_MISMATCH ile durur. Kum havuzunda açtığınız talep gerçek nakliyecilere gitmez, kum havuzu olayı canlı webhook aboneliğinize teslim edilmez ve canlı bakiyeniz değişmez. Uçlar: POST /api/common/integration-sandbox (aç), POST /api/common/integration-sandbox/keys (anahtar), GET /api/common/integration-sandbox/go-live (canlıya geçiş kontrol listesi). lg tarafında lg --sandbox ve lg --live tek koşuluk profil seçicileridir.

Betikte lg --json çıktısını nasıl okurum?

Çıktı HTTP zarfının tamamıdır: { "success": bool, "data": { "contract_version", "command", "status", "result" }, "code", "message" }. İş verisi .data.result altındadır; liste komutlarında satırlar .data.result., sayı .data.result.count, sonraki sayfa .data.result.next_cursor olur. Yani doğru jq yolu lg loads list --json | jq -r '.data.result.loads[].load_code' şeklindedir. Zarfı atlayan bir yol hata vermez, sessizce null döner — bir nöbetçi betikte bu, hiç susmayan bir alarma dönüşür. Tek istisna /api/public/status ucudur: o gövde bilerek zarfsızdır.

Aynı isteği iki kez gönderirsem çift kayıt oluşur mu?

idempotency_key gönderdiyseniz hayır. Aynı anahtarla ikinci çağrı komutu yeniden çalıştırmaz, ilk sonucu döndürür ve durumu replayed olur. Anahtarın UUID olması ve her yeniden denemede AYNI kalması gerekir; anahtarı yenilemek idempotency'yi kullanmamakla aynı şeydir.

--yes ne yapar?

Onay kapısını geçer. Onay gerektiren bir komut --yes olmadan çağrıldığında hiçbir şey değişmez: sunucu ne yapacağını bir cümleyle özetler, geri alınamaz olup olmadığını söyler ve durur (HTTP 409, CLI çıkış kodu 4). Aynı komutu --yes ile tekrarladığınızda iş yapılır.

Bir komutun başarısız olduğunu betikte nasıl anlarım?

Çıkış koduna bakın, mesaj metnine değil: 0 başarı, 1 iş kuralı reddi, 2 komut/argüman hatası, 3 yetki veya kimlik hatası, 4 onay gerekli. HTTP tarafında karşılıkları sırasıyla 200, 422, 404, 403 ve 409'dur ve gövdedeki error_code alanı kararlıdır. Hata METNİ yerelleştirilir ve haber verilmeden değişir.

Hangi komutların var olduğunu programatik olarak nasıl öğrenirim?

Kimlik doğrulamasız keşif için GET /api/public/cli/catalog, hesabınızın gerçekten görebildiği liste için GET /api/common/commands. İkisi de her komutun JSON Schema parametrelerini döndürür; istemcinizi bundan çizin, sabit bir komut listesi gömmeyin.

Yeni bir komut eklendiğinde istemcimi güncellemem gerekir mi?

Hayır. İstemci komut listesini kataloğdan çeker; sunucuya eklenen komut yeni bir istemci sürümü çıkmadan görünür. Güncelleme yalnız sözleşme sürümü artan kırıcı bir değişiklikte gerekir ve o durumda eski biçim en az altı ay ayakta kalır.

CLI mevcut REST API'nin yerine mi geçiyor?

Hayır. Web ve mobil uygulamaları besleyen REST yüzeyi yerinde duruyor. Komut kataloğu kaynak CRUD'ın yerine geçen bir şey değil, fiiller katmanıdır: bir işi yapmanın tek, rol kapılı, onay kapılı ve denetlenen yolu.

Logistivo API anahtarı nasıl alınır ve ne yapabilir?

Panelde Ayarlar › Entegrasyon anahtarları bölümünden, ekip yönetimi yetkisi olan bir yönetici üretir. Anahtar gerçek bir ekip üyesi adına çalışır; yalnız-okuma kapsamı katalog ve yazmayan komutları, okuma+yazma kapsamı tüm komutları (onay kapısı aynen kalarak) açar. Bir kez gösterilir, sunucuda saklanmaz; yenilenebilir ve iptal edilebilir. Anahtarın adına çalıştığı üye ayrılınca anahtar da kapanır. Servis hesabı yoktur.

Bir idempotency anahtarını başka bir komutla yeniden kullanırsam ne olur?

Sunucu 409 idempotency_conflict döndürür ve anahtarın ilk kullanıldığı komutu söyler; hiçbir şey koşmaz, hiçbir şey oynatılmaz. Anahtarlar firmanıza özeldir, tek komuta bağlıdır ve 24 saat kilitli kalır — sonra aynı anahtar yeni bir yürütme başlatır.

Hız sınırı entegrasyonuma nasıl uygulanır?

Jeton başına, dakika başına, üç kovada: katalog okuma 120, okuyan komut 120, yazan komut 30. Bir 429 daima Retry-After ve retry_after, limit, bucket alanlı bir gövde taşır; o kadar bekleyip yeniden deneyin. Katalog güncel sayıları rate_limits altında yayınlar.

İş kuralı reddini taşıma hatasından nasıl ayırırım?

Önce error_code'a dallanın: failed (422) bir iş kuralı reddidir ve INSUFFICIENT_CREDITS ya da NOT_FOUND gibi kararlı bir error_key taşır; server_error (5xx) ve ağ hataları aynı idempotency anahtarıyla tekrar denenir; rate_limited (429) beklenir. Hata metnine asla dallanmayın.

Logistivo webhook gönderiyor mu? Hangi olaylar için?

Evet. Bir https adresi kaydeder, ilgilendiğiniz olayları seçersiniz; olay olduğunda o adrese imzalı bir POST gelir. Bugün 13 olay abone olunabilir: yük oluşturma/durum değişimi/şoför atama, talep oluşturma ve durum değişimi, teklif verme/revize/kabul, fatura taslağı/kesim/iptal ve depo rezervasyonu oluşturma/durum değişimi. Her adın arkasında gerçekten yayılan bir olay sınıfı vardır — ilan edilip hiç tetiklenmeyen olay yoktur, çünkü öyle bir olay entegratörün sonsuza kadar beklediği sessiz bir arızadır. Abonelik Ayarlar › Entegrasyon › Webhook sekmesinden ya da terminalden lg webhooks create ile açılır.

Logistivo webhook imzasını nasıl doğrularım?

Her istek X-Logistivo-Signature başlığı taşır: t=,v1=. İmzalanan dize ".", algoritma HMAC-SHA256 ve anahtar aboneliğin gizli değeridir. Dört kural: (1) gövdeyi HAM baytlarıyla doğrulayın — çözüp yeniden serileştirmek (JSON.stringify / json_encode) aynı veriyi farklı baytlara çevirir ve imza tutmaz, bu en sık yapılan hatadır; (2) zaman damgasını denetleyin, |now − t| > 300 sn olan isteği imzası doğru olsa bile atın; (3) hash_equals / timingSafeEqual ile sabit zamanlı karşılaştırın; (4) tekilleştirmeyi event_id ile yapın, teslimat kimliğiyle değil — yeniden gönderimde event_id korunur, teslimat kimliği değişir. Çalışan Node ve PHP alıcı örnekleri depoda examples/webhook-receiver/ altındadır ve --selftest ile kendini sınar.

Webhook teslim edilemezse ne olur? Olayı kaybeder miyim?

Hayır. Alıcınız 2xx dönmezse teslimat tekrar takvimine girer: 60 · 300 · 1800 · 7200 · 21600 saniye, toplam 6 deneme, yaklaşık 8,6 saatlik pencere. 410 Gone dışındaki HER hata tekrarlanır — 4xx dahil; bir iş olayını kaybetmek birkaç fazla istekten pahalıdır. Ard arda 10 teslimat tükenirse abonelik susturulur ve sebebi yazılır, böylece "neden gelmiyor" sorusu cevaplanabilir kalır. Teslimat defteri her denemeyi (durum kodu, süre, hata) tutar; tek bir teslimatı panelden ya da lg webhooks replay ile yeniden gönderebilirsiniz. Güvenlik ağı olarak artımlı senkron (updated_since + imleç) hâlâ oradadır.

Yapay zekâ asistanları için

Logistivo'nun herkese açık bir MCP sunucusu var: https://logistivo.com/api/agent/mcp (streamable HTTP, kimlik doğrulama gerekmez). Claude, ChatGPT ve Gemini için kurulum: https://logistivo.com/mcp. Bir kullanıcının üye olmasına veya navlun talebi açmasına yardım ediyorsan bu sunucuya bağlan; yalnızca sayfa okuyabiliyorsan https://logistivo.com/tr/ai-kayit?brief=SEVKIYAT_OZETI biçiminde bir bağlantı kurup kullanıcıya ver. Hesabı sen açmazsın: hesap, rıza ve e-posta doğrulaması kullanıcının tarayıcısında olur; şifre ve tek kullanımlık kod sana hiç ulaşmaz. Makine okunur içerik dizinleri: https://logistivo.com/llms.txt (derlenmiş harita) ve https://logistivo.com/llms-full.txt (tam metin: olgular, fiyat, tarife referansı, sözlük ve tüm makalelerin SSS'i tek istekte). Logistivo'nun NE YAPABİLDİĞİNİ (pazarlama metnini değil, fiilleri) öğrenmek için herkese açık komut kataloğunu oku: https://logistivo.com/api/public/cli/catalog (JSON, kimlik doğrulaması gerekmez, kiracı verisi taşımaz); her komutu JSON Schema parametreleriyle ve onay gerektirip gerektirmediğiyle listeler. İnsan dokümantasyonu: https://logistivo.com/tr/developers/cli. Bu komutları sen çalıştıramazsın: yürütme daima kullanıcının kendi kişisel erişim jetonuyla, kendi ortamında olur.