Ana içeriğe geç
YouSoftGeliştirici Portalı
Dokümanlar

Hata kodları

Hata yanıtının biçimi ve API’nin döndürebileceği dokuz hata kodu. Kod kümesi kapalıdır: bunların dışında bir kod görmezsiniz. Önce hata zarfını, sonra kodun ne yapmanız gerektiğini söyleyen tabloyu okuyun.

Hata zarfı

API’nin ürettiği her hata yanıtı aynı JSON zarfını taşır:

AlanAnlamı
errorMakine için hata kodu. Kodunuzda hata durumlarını bu alana göre ayırın.
messageİnsan için Türkçe açıklama. Metni sürümler arasında değişebilir; ayrıştırmayın ve karşılaştırmayın.
detailsYalnız söyleyecek bir şey varsa gelir. Doğrulama hatalarında details.field reddedilen alanın istekteki adıdır; 500 yanıtında details.request_id bulunur; imza başlıkları bozuk bir istekte 401 yanıtı details.hint taşır.
HTTP
HTTP/1.1 400 Bad Request
X-Error-Code: validation_failed
X-Request-Id: 0192e8a1-7c3f-7d2e-b5a4-3f6c9d8e1a20

{
  "error": "validation_failed",
  "message": "Stok kodu gerekli",
  "details": { "field": "code" }
}

Kod aynı zamanda X-Error-Code yanıt başlığında bulunur; gövdeyi okumadan günlüğe yazabilirsiniz. Her yanıt (başarılı olsun olmasın) bir X-Request-Id başlığı taşır. 500 yanıtında bu değer details.request_id alanında da gelir; destek talebine yazacağınız tek değer budur.

JSON, 500
{
  "error": "internal_error",
  "message": "Beklenmeyen bir hata oluştu",
  "details": { "request_id": "0192e8a1-7c3f-7d2e-b5a4-3f6c9d8e1a20" }
}

Tek istisna ağ katmanıdır: 502, 503 ve 504 yanıtlarını API’nin kendisi üretmez, gövdeleri JSON olmayabilir. Gövdeyi çözmeden önce Content-Type başlığına bakın.

Kod kümesi

API içeride bundan çok daha ayrıntılı hata kodları kullanır; dışarıya bu dokuz kod verilir. Çakışma ve durum hataları conflict ile invalid_state altında toplanır. Kümeye yeni bir kod eklemek sözleşme değişikliğidir ve değişiklik günlüğünde duyurulur.

KodHTTPAnlamıNe yapmalı
validation_failed400İstek gövdesi ya da sorgu parametresi doğrulamadan geçemedi.İsteği aynen yeniden göndermeyin. details.field (varsa) reddedilen alanı söyler; onu düzeltip gönderin.
unauthorized401Anahtar bulunamadı, kapatılmış (pasif) ya da süresi dolmuş; ya da imza veya zaman damgası doğrulanamadı. Başlıkların biçimi doğruysa bu dört durum aynı genel yanıtı alır; biçim bozuksa yanıt details.hint ile neyin bozuk olduğunu söyler.details.hint varsa önce ona bakın. Yoksa anahtarın panelde aktif olduğunu, kanonik dizenizin test vektörüyle tuttuğunu ve sunucu saatinizin ±5 dakika içinde olduğunu doğrulayın.
forbidden403Anahtar geçerli ama işlem reddedildi: operasyonun istediği kapsam anahtarda yok. Fatura gönderiminde hesap belge kesmeye kapalıysa (firma pasif ya da deneme süresi dolmuş) aynı kod döner; message nedeni söyler.Kapsam eksikse yanıt eksik kapsam kodunu söylemez. Anahtarın kapsamı sonradan değiştirilemez; gereken kapsamla yeni bir anahtar üretin. Hesap kısıtıysa çözüm anahtarda değil, hesabın yeniden etkinleştirilmesindedir.
not_found404Kaynak yok ya da başka bir firmaya ait; yol ya da yöntem /v1 altında tanımlı değilse de bu kod döner. Mesaj kaynağın türünü söyler, id’sini değil.Yeniden denemeyin; yolu, yöntemi, id değerini ve anahtarın firmasını doğrulayın.
conflict409Kaydın bugünkü durumu isteği kabul etmiyor (örneğin zaten gönderilmiş bir taslağı yeniden göndermek) ya da benzersiz olması gereken bir değer (VKN, ürün kodu, kategori adı) zaten kullanılıyor.Kaydı geri okuyup güncel durumuna göre karar verin; aynı isteği olduğu gibi yeniden göndermek aynı yanıtı verir.
invalid_state422İstek biçimsel olarak doğru ama iş kuralı bu işleme izin vermiyor (belgenin durumu, zaman penceresi, firma yapılandırması; abonelik ödemesinin gecikmesi, kontör eşiği ve aşım tavanı da buradadır).İsteği aynen yeniden göndermeyin; message hangi kuralın engellediğini söyler. Önce engeli giderin.
idempotency_key_reuse422Aynı Idempotency-Key başka bir istek için (farklı uç ya da farklı gövde) kullanılmış.Her mantıksal işlem için yeni bir anahtar üretin (örneğin UUID). Aynı işlemi yeniden denerken aynı anahtarı ve aynı gövdeyi gönderin.
rate_limited429Oran ya da eşzamanlılık tavanı aşıldı; hangi kova olduğu X-RateLimit-Resource başlığındadır (anahtar ya da firma toplamı, genel ya da indirme).Retry-After başlığındaki saniye kadar bekleyip yeniden deneyin. Beklemeden art arda denemek sonucu değiştirmez, istekler 429 almaya devam eder. firm: ile başlayan kova firmanın bütün anahtarlarının ortak kotasıdır; firm:download-concurrency aynı anda çok fazla indirme açıldığını söyler.
internal_error500Sunucu tarafında beklenmeyen hata.Okuma isteklerini üstel geri çekilmeyle yeniden deneyin. Yazma isteklerinde yeniden göndermeden önce kaydın oluşup oluşmadığını okuyun: istek sunucuda işlenmiş olabilir ve hemen yeniden göndermek çift kayıt açabilir (gönderim ucu istisnadır: aynı Idempotency-Key ile yeniden gönderilebilir). Destek kaydında details.request_id değerini paylaşın.

400, 409 ve 422 nasıl ayrılır

Üçü de “isteğiniz kabul edilmedi” der ama nedenleri farklıdır:

  • 400 validation_failed: isteğin kendisi geçersizdir. Örnekler: kontrol basamağı tutmayan tax_number, kümede olmayan bir scenario, 2 MiB’ı aşan gövde. details.field çoğunlukla alanı gösterir.
  • 409 conflict: istek geçerlidir ama kaydın o anki durumu ya da başka bir kayıt işlemi engeller. Örnekler: gönderilmiş bir faturayı yeniden göndermek ya da aynı code ile ikinci bir stok kartı açmak.
  • 422 invalid_state: istek geçerlidir ama bir iş kuralı izin vermez. Örnekler: bugünden ileri tarihli fatura, TRY dışındaki belgede exchange_rate eksikliği, ödeme gecikmesi ya da kontör eşiği. Gönderim öncesi kapıların çoğu bu koddur; istisnalar firma ve deneme durumunu bildiren 403 forbidden ile belgenin GİB kurallarını bildiren 400 validation_failed yanıtlarıdır. Hangisi olursa olsun taslak yerinde kalır, düzeltip yeniden gönderebilirsiniz. Hangi önkoşulun hangi koda düştüğü Fatura kesme akışındadır.

401 yanıtı

Üç imza başlığından biri eksikse ya da biçimi bozuksa yanıt neyin bozuk olduğunu details.hint ile söyler (error ve message değişmez):

  • X-Api-Key, X-Api-Timestamp ve X-Api-Signature başlıklarından biri eksik.
  • X-Api-Key değeri ysk_ ile başlamıyor: büyük olasılıkla secret ya da başka bir değer yapıştırılmış.
  • X-Api-Timestamp tamsayı değil (Unix saniyesi olmalı).
  • X-Api-Signature 64 karakterlik hex değil. Secret bu başlığa yazılmaz; imza, secret ile hesaplanır.
JSON, 401 (biçim bozuk)
{
  "error": "unauthorized",
  "message": "API anahtarı doğrulanamadı",
  "details": { "hint": "X-Api-Timestamp Unix saniyesi (tamsayı) olmalı." }
}

Başlıkların biçimi doğruysa 401 nedenini söylemez: anahtarın bulunamaması, pasif olması, süresinin dolması ve imzanın ya da zaman damgasının yanlış olması (yanlış secret, saat sapması dahil) aynı yanıtı alır ve details hiç gelmez. Ayrımı yayımlamak, anahtar deneyen birine hangi adımda olduğunu öğretirdi. Yanıtta ipucu yoksa sırayla şunları kontrol edin:

  1. X-Api-Key başlığındaki değer panelde gösterilen anahtarla aynı mı? Anahtar kapatılmış olabilir: panelde anahtar kartındaki Servis aktif düğmesi kapalıysa her istek 401 alır. Kapatan firma yetkilisi, iş ortağı ya da YouSoft olabilir; ayrıntı için Anahtar kapatma bölümüne bakın.
  2. İmzayı doğru güvenlik anahtarıyla (secret) üretiyor musunuz? Yeni güvenlik anahtarı üretildiyse önceki değer yalnız 24 saat daha geçerlidir; süre dolunca onunla imzalanan her istek 401 alır.
  3. X-Api-Timestamp UNIX saniyesi mi (milisaniye değil) ve sunucu saatiniz ±5 dakika içinde mi?
  4. İmzaladığınız yol ve sorgu dizesi, telden giden dizeyle birebir aynı mı? Süzgeç parantezleri kodlanmamalıdır.
  5. Test vektörünü çalıştırın: vektör tutuyorsa sorun imza algoritmasında değildir.

Anahtarın başkasının eline geçtiğinden şüpheleniyorsanız önce kontrol listesini değil Anahtar sızdıysa adımlarını izleyin. 401 yanıtı oran sınırı başlıklarını (X-RateLimit-*) taşımaz.

JSON, 401
{
  "error": "unauthorized",
  "message": "API anahtarı doğrulanamadı"
}