Özel indirim uygulaHerhangi bir servis için (Facebook, Instagram ve Apple hariç) günde 2000'den fazla Gmail OTP kiralayan ve özel indirim isteyenler bana mesaj atabilir; yeterince büyük miktarda hesap açanlar için orijinal fiyattan %50'ye varan indirim sağlanabilir.
New update 29/09I have just added 4 new warehouses for all services + short-live accounts shop (24h) with email + pass for you to log in, feel free to check them out when you have time

API belgeleri

Herkese açık API /v1 — bir API anahtarıyla kimlik doğrulayın ve gelen kutusu kiralamalarını kendi yazılımınızdan otomatikleştirin

API anahtarınız
Giriş yapmadınız — kendi API anahtarınızı almak için giriş yapın.
Bu anahtarı Authorization: Bearer <key> başlığında veya ?api_key=<key> sorgu parametresinde gönderin. Anahtarın tamamını görmek için göz simgesine tıklayın; değiştirmeniz gerektiğinde Yeni anahtar oluştur düğmesine tıklayın (eski anahtar hemen çalışmaz hale gelir).

Genel bakış

Temel URL
https://otpgmail.net
Kimlik doğrulama
API anahtarınızı her isteğe ekleyin: Authorization: Bearer og_xxx... başlığında (önerilir) veya ?api_key=og_xxx... sorgu dizesinde.
Idempotency-Key (yinelenen siparişleri önler)
Her POST /v1/orders isteği Idempotency-Key: <sipariş başına yeni UUID> başlığını içermelidir. İstek zaman aşımına uğrarsa veya bağlantı kesilirse isteği aynı anahtarla yeniden gönderin — sunucu yeni bir sipariş oluşturmak yerine orijinal yanıtı döndürür. Her yeni sipariş için yeni bir UUID üretin; bir UUID'yi yalnızca yeniden denerken tekrar kullanın.
Aynı anda çok sayıda sipariş: tek çağrıda durum
Onlarca, yüzlerce gelen kutusu mu kiralıyorsunuz? Durumlarını tek tek değil birlikte okuyun: POST /v1/orders/status çağrı başına en fazla 100 sipariş döndürür (istek sınırınıza tek istek olarak sayılır), GET /v1/orders ise siparişlerinizi listeler — yeniden başlattıktan sonra ?status=waiting_code hâlâ kod bekleyen tüm siparişleri geri verir. Her hata ayrıca yeniden denemeye değip değmeyeceğini de söyler (error.retryable, error.retryAfterSec). Ayrıntılar: Çok sayıda siparişin durumu bölümü.
Gelen kutusu türü: Gmail veya iCloud
Varsayılan olarak bir @gmail.com gelen kutusu alırsınız. @icloud.com gelen kutusu kiralamak için POST /v1/orders gövdesine "domain": "icloud.com" ekleyin. domain belirtilmezse gmail.com anlamına gelir — mevcut entegrasyonlar değişiklik yapmadan çalışmaya devam eder. iCloud yalnızca GET /v1/services yanıtında icloud alanı null olmayan hizmetler için kullanılabilir; iCloud fiyatı Gmail fiyatından farklı olabilir (bkz. icloud.price). Her sipariş yanıtı, siparişin hangi gelen kutusu türünü kullandığını gösteren bir domain alanı içerir. Bazı hizmetler ayrıca @gmx.com gelen kutuları sunar (şu anda yalnızca Pokemon, kod pkm, kaynak 2): "domain": "gmx.com" gönderin — bir hizmetin GET /v1/services yanıtındaki offers[] dizisinde domain = "gmx.com" olan bir kayıt varsa bunu sunar; diğer tüm hizmetler ⇒ DOMAIN_UNAVAILABLE. gmx.com toplu siparişlerde kullanılamaz.
Kaynaklar (warehouse): tek hizmet, birden fazla gelen kutusu kaynağı
Bir hizmet, her biri kendi fiyatına, stokuna ve kod kurallarına sahip birden fazla kaynaktan (warehouse) satılabilir (GET /v1/services içindeki offers[] dizisi). Birini seçmek için sipariş oluştururken "warehouse": 2 gönderin; "warehouse": 99 ⇒ sistem stokta olan en ucuz kaynağı seçer, tükenirse bir sonrakine geçer (Facebook ve Instagram gibi sık tükenen hizmetler için idealdir); 0 ⇒ stokta olan en ucuz kaynak. Mevcut istemcilerde değişiklik gerekmez: warehouse belirtilmezse ⇒ eskisi gibi kaynak 1 kullanılır ve price, stock ile icloud kaynak 1'i tanımlar (kaynak 1'i olmayan hizmetlerde ⇒ stokta olan en ucuz kaynak). Ayrıntılar için bkz. Kaynaklar.
Toplu kiralama (toplu siparişler)
Toplu siparişler web'de (Toplu kiralama sayfası) satın alınır; API ile toplu siparişleri listeleyip kodları okuyabilirsiniz. Gmail (Kaynak 1): her gelen kutusunun, API anahtarı gerektirmeyen bir kod bağlantısı olan proxyUrl alanı vardır. iCloud (Kaynak 3): özel gelen kutuları; kodları GET /v1/batches/{id}/mails/{mailId}/codes ile okuyun veya web'de readUrl adresini açın. Ayrıntılar: Toplu kiralama bölümü.
Kısa ömürlü Gmail hesabı satın alma (mail shop)
Gelen kutusu kiralamanın yanı sıra 2 mail kaynağından Gmail hesaplarını bütünüyle satın alabilirsiniz — kaynak 1: e-posta, şifre, çerezler + gelen kutusu bağlantısı (JSON olarak da); kaynak 2: e-posta, şifre + hızlı giriş bağlantısı; kaynak 99 önce en ucuzunu seçer (web'deki Kısa ömürlü Gmail satın al sayfası). API, o sayfanın yaptığı her şeyi yapar: kaynakları, fiyatları ve stoku görme, satın alma (Idempotency-Key zorunlu), teslimatı izleme, hesapları indirme ve e-postalarını okuma. Ayrıntılar: Kısa ömürlü Gmail satın alma bölümü.
Müşterileriniz kodları kendileri görsün (/otp sayfası)
Kiraladığınız gelen kutularını (web'de ya da API ile) yeniden mi satıyorsunuz? Hesabım sayfasında bir paylaşım kodu açın, sonra müşterinize https://otpgmail.net/tr/otp#k7m2q9:[email protected] bağlantısını gönderin (k7m2q9 = paylaşım kodunuz) — o e-postanın en son kodlarını giriş yapmadan görürler, fiyatları veya bakiyenizi asla görmezler; sayfa yalnızca ücretsiz işlemler yapar (sizden asla ücret almaz).
Araçlar / botlar için JSON bağlantısı (sizin ya da müşterinizin): yol biçimindeki https://otpgmail.net/tr/otp/k7m2q9:[email protected] bağlantısını alın (# bağlantısı gibi /otp sayfasını açar) ve sonuna ?json ekleyin ⇒ sunucu, sayfanın gösterdiği verinin aynısını JSON olarak döndürür: cards[] — o e-postada kiralanan her hizmet için bir kart (email, serviceName, state, items[] = en yeniden başlayarak en fazla 5 kod / bağlantı) — ve serverTime. state: waiting ilk kod bekleniyor · listening yeni kod bekleniyor · received kod geldi · needs_owner satıcının uzatması gerekir · expired süresi doldu · banned posta kilitlendi. Birden fazla e-posta: virgülle ayırın (en fazla 50). API anahtarı ve çerez gerekmez, CORS açık; yalnızca okuma (“Yeni OTP yükle” / “Bu e-postayı yeniden kirala” /otp sayfasında kalır). Sayfayla aynı tahmin önleme sınırları: yanlış kod / e-postada gösterilecek sipariş yok ⇒ 404 NOT_FOUND; tekrarlanan hatalar veya bir e-posta için dakikada 30'dan fazla okuma ⇒ 429 RATE_LIMITED ve retryAfter (saniye). /otp#… bağlantısına ?json eklemek JSON döndürmez: tarayıcılar # işaretinden sonrasını sunucuya hiç göndermez.
curl "https://otpgmail.net/tr/otp/k7m2q9:[email protected]?json"
{
  "success": true,
  "data": {
    "cards": [
      {
        "ref": "Q3vX9kL2mP0aB7cD",
        "serviceCode": "fb",
        "serviceName": "Facebook",
        "logo": "/logos/fb.png?v=20261007",
        "domain": "gmail.com",
        "email": "[email protected]",
        "state": "received",
        "until": null,
        "items": [
          {
            "kind": "code",
            "value": "529170",
            "label": null,
            "at": 1760000405
          },
          {
            "kind": "code",
            "value": "381904",
            "label": null,
            "at": 1759999030
          }
        ],
        "total": 2,
        "canLoad": true
      }
    ],
    "serverTime": 1760000530
  }
}
GitHub'da eksiksiz örnek kod
Python, Node.js, PHP, C# (.NET) ve curl için çalıştırmaya hazır istemciler — gelen kutusu kiralayın, kodu bekleyin, iade için otomatik iptal edin ve stok tükendiğinde iCloud ile Gmail arasında geçiş yapın: github.com/letoan0902/otpgmail-email-otp-api (İngilizce) · thue-otp-gmail (Vietnamca). Python notu: yalın urllib yerine requests kullanın (varsayılan User-Agent'ı CDN'den 403 alır).
Webhook'lar
Her siparişi sürekli sorgulamak yerine bir URL kaydedin; bir sipariş yeni kod aldığında veya iptal edilip iade edildiğinde imzalı bir POST alırsınız — bkz. Webhook'lar.

Uç noktalar

GET/v1/balance
İstekte kullanılan API anahtarına ait hesap bakiyesini (VND cinsinden) döndürür.
Örnek
curl "https://otpgmail.net/v1/balance" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "balance": 25000
  }
}
Olası hatalar: UNAUTHORIZED
GET/v1/services
Etkin hizmetleri listeler — kod, ad, Gmail fiyatı (VND cinsinden) ve güncel Gmail stoku, @icloud.com gelen kutularının fiyatını ve stokunu içeren bir icloud bloğu ve bir offers[] dizisi: hizmeti satan her kaynak için, kaynak × gelen kutusu türü başına bir kayıt (fiyat, stok, kod sayısı, kurallar). Veriler önbelleğe alınır: stok yaklaşık 30–60 saniyede bir, fiyatlar daha seyrek yenilenir.
icloud = null, hizmetin henüz iCloud'u desteklemediği anlamına gelir (sağlayıcı sunmuyor veya geçici olarak devre dışı) — yalnızca Gmail kiralanabilir. icloud bloğu olan hizmetlerde, icloud.price fiyatıyla bir @icloud.com gelen kutusu almak için sipariş oluştururken "domain": "icloud.com" gönderin. price / stock / icloud.price, kaynak 1'i tanımlar — warehouse belirtilmeyen siparişler oraya gider (kaynak 1'i olmayan hizmetlerde ⇒ stokta olan en ucuz kaynak); kaynak bazında fiyat ve stok offers[] içindedir (bkz. Kaynaklar). stock, sağlayıcının yayımladığı sayıdır (kaynak 1: yaklaşık her 30 saniyede bir yenilenir) ve tek bir çağrının o kadarını kiralayabileceğini garanti etmez: gelen kutuları tek tek atanır ve sağlayıcı yarıda tükenebilir — bu durumda POST /v1/orders daha az sipariş ve bir partial alanı döndürür. Kaynak 2 ve 4 de kendi sağlayıcılarının sayılarını gösterir.
Örnek
curl "https://otpgmail.net/v1/services" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": [
    {
      "code": "dr",
      "name": "OpenAI (ChatGPT)",
      "price": 350,
      "stock": 616525,
      "icloud": {
        "price": 630,
        "stock": 12464
      },
      "offers": [
        {
          "warehouse": 2,
          "domain": "gmail.com",
          "price": 350,
          "stock": 616525,
          "maxCodes": null,
          "rules": null,
          "fee": {
            "freeHours": 6,
            "paidPct": 50,
            "maxHours": 24
          },
          "isDefault": true
        },
        {
          "warehouse": 1,
          "domain": "gmail.com",
          "price": 630,
          "stock": 12464,
          "maxCodes": 3,
          "rules": null,
          "fee": null,
          "isDefault": false
        },
        {
          "warehouse": 1,
          "domain": "icloud.com",
          "price": 630,
          "stock": 12464,
          "maxCodes": 5,
          "rules": null,
          "fee": null,
          "isDefault": true
        }
      ],
      "note": null
    },
    {
      "code": "fb",
      "name": "Facebook",
      "price": 1590,
      "stock": 88,
      "icloud": null,
      "offers": [
        {
          "warehouse": 1,
          "domain": "gmail.com",
          "price": 1590,
          "stock": 88,
          "maxCodes": 10,
          "rules": null,
          "fee": null,
          "isDefault": false
        },
        {
          "warehouse": 4,
          "domain": "gmail.com",
          "price": 1580,
          "stock": 2310,
          "maxCodes": null,
          "rules": null,
          "fee": null,
          "isDefault": true
        }
      ],
      "note": null
    }
  ]
}
Olası hatalar: UNAUTHORIZED
POST/v1/orders
Doğrulama kodlarını alan bir gelen kutusu için sipariş oluşturur — varsayılan olarak Gmail, domain: "icloud.com" gönderirseniz iCloud. Sağlayıcı gelen kutusunu atar atamaz bakiyenizden ücret düşülür. Bir sipariş listesi döndürür (bir tane veya quantity > 1 ise birkaç tane).
Eksik teslimat: quantity bir üst sınırdır
  • Gelen kutuları tek tek atanır. Sağlayıcı yarıda tükenirse (örneğin kaynak 1'de o an o hizmet için gelen kutusu kalmadıysa) çağrı durur ve o ana kadar oluşturulan siparişlerle birlikte HTTP 200 döndürür — data, quantity değerinden kısa olabilir ve yalnızca data içindeki siparişler için ücret alınır. GET /v1/services içindeki stock, tek bir çağrının kaç tane alacağını garanti etmez.
  • Bu durumda yanıtta data alanının yanında üst düzey bir partial alanı da bulunur (her şey teslim edildiyse yoktur; yalnızca data okuyan botlar değişiklik gerektirmez): requested, delivered, missing ve reason = {code, message, retryable, retryAfterSec}; code, çağrıyı durduran hatadır (NO_MAILS_AVAILABLE, OUT_OF_STOCK, ALL_WAREHOUSES_EXHAUSTED, INSUFFICIENT_BALANCE, WAITING_LIMIT_REACHED…).
  • Tükenme genellikle geçicidir — kaynak 1'de sağlayıcının birkaç saniye sonra çoğu zaman yine gelen kutusu olur. reason.retryable = true ise reason.retryAfterSec saniye (3–5 sn) bekleyin, ardından missing kadar gelen kutusunu YENİ bir Idempotency-Key ile tekrar isteyin (eski anahtar yalnızca bu yanıtı aynen yeniden döndürür); hepsini alana kadar yineleyin.
  • Eksik teslimattan hemen sonraki çağrı 409 WAREHOUSE_UNAVAILABLE / OUT_OF_STOCK veya 503 NO_MAILS_AVAILABLE döndürebilir — bu normaldir: çağrılar arasında 3–5 sn beklemeye devam edin ve ancak art arda çok sayıda çağrı başarısız olursa (örneğin 10 deneme, yaklaşık bir dakika) vazgeçin; ardından daha sonra yeniden deneyin ya da sistemin başka kaynaklara geçmesi için "warehouse": 99 gönderin. retryable = false (INSUFFICIENT_BALANCE, WAITING_LIMIT_REACHED…) ⇒ önce nedeni giderin (bakiye yükleyin veya açık siparişlerin bitmesini bekleyin).
  • Hata yanıtları da aynı iki alanı error içinde taşır: error.retryable ve error.retryAfterSec (ör. 409 OUT_OF_STOCK ⇒ true, 5; 402 INSUFFICIENT_BALANCE ⇒ false, null) — Hata kodları bölümüne bakın.
Idempotency-Key başlığı (bir UUID) zorunludur. Her yeni kiralama için yeni bir UUID üretin; zaman aşımından sonra yeniden denerken yinelenen sipariş oluşmaması için AYNI anahtarı kullanın. Bu çağrı, sağlayıcının bir gelen kutusu atamasını bekler; bu yüzden genellikle yaklaşık 0,3 saniye sürer ancak yoğun saatlerde (nadiren) 10 saniyeye kadar çıkabilir — 5 saniye sonra vazgeçip erken yeniden denemek yerine istemci zaman aşımınızı yaklaşık 15 saniyeye ayarlayın.
Parametreler
AdTürZorunluAçıklama
servicestringEvetHizmet kodu (GET /v1/services yanıtından, örn. "ig", "tg", "fb")
quantitynumberHayırKiralanacak AZAMİ gelen kutusu sayısı (varsayılan 1; istek başına en fazla 200) — kaynak yarıda tükenirse daha azını alırsınız: data[] öğelerini sayın ve partial alanını okuyun
domainstringHayırGelen kutusu türü: "gmail.com" (varsayılan), "icloud.com" veya "gmx.com". Belirtilmezse = gmail.com — mevcut entegrasyonlarda değişiklik gerekmez. iCloud yalnızca GET /v1/services yanıtında icloud alanı null olmayan hizmetler için kiralanabilir; "gmx.com" yalnızca offers[].domain = "gmx.com" olan hizmetler için (şu anda yalnızca Pokemon, kod pkm) — aksi halde çağrı DOMAIN_UNAVAILABLE ile başarısız olur. Başka herhangi bir değer ⇒ VALIDATION_ERROR.
warehousenumberHayırKiralanacak kaynak. Belirtilmezse = KAYNAK 1, çoklu kaynak desteğinden önceki davranışın aynısı (kaynak 1'i olmayan hizmetler en ucuz kaynağa düşer) — mevcut istemcilerde değişiklik gerekmez. 0 = stokta olan en ucuz kaynak (yalnızca bir kaynak denenir). 1–4 = tam olarak o kaynak (GET /v1/services içindeki offers[].warehouse değeri); bu hizmeti/gelen kutusu türünü satmıyorsa, duraklatılmışsa veya stoğu tükenmişse ⇒ WAREHOUSE_UNAVAILABLE. 99 = OTOMATİK: stokta olan kaynaklar en ucuzdan en pahalıya doğru denenir, biri tükenirse veya hata verirse sonrakine geçilir; hiçbiri kalmazsa ⇒ ALL_WAREHOUSES_EXHAUSTED — sık tükenen hizmetler (Facebook, Instagram…) için önerilir. Bkz. Kaynaklar.
Örnek
# Her YENİ sipariş için rastgele bir Idempotency-Key üretin
# Zaman aşımından sonra yeniden denerken AYNI anahtarı tekrar kullanın (yinelenen siparişleri önler)
# domain: "gmail.com" (varsayılan, isteğe bağlı) | "icloud.com" (@icloud.com gelen kutusu kirala) | "gmx.com" (yalnızca sunan hizmetler, örn. Pokemon)
# warehouse: 0 | 1–4 | 99 (isteğe bağlı — eskisi gibi kaynak 1 için belirtmeyin; 0 = stokta olan en ucuz kaynak; 99 = otomatik, bir kaynak tükenince sonrakine geçer; bkz. GET /v1/services içindeki offers[])
curl -X POST "https://otpgmail.net/v1/orders" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"service":"ig","quantity":1,"domain":"gmail.com"}'
Örnek yanıt
{
  "success": true,
  "data": [
    {
      "orderId": "abc123xyz",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270000,
      "rentExpiresAt": 1753356400,
      "createdAt": 1753268200,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    }
  ]
}
Örnek yanıt — eksik teslimat (quantity 5, 2 gelen kutusu teslim edildi)
{
  "success": true,
  "data": [
    {
      "orderId": "abc123xyz",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270000,
      "rentExpiresAt": 1753356400,
      "createdAt": 1753268200,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    },
    {
      "orderId": "jkl012mno",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270001,
      "rentExpiresAt": 1753356401,
      "createdAt": 1753268201,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    }
  ],
  "partial": {
    "requested": 5,
    "delivered": 2,
    "missing": 3,
    "reason": {
      "code": "NO_MAILS_AVAILABLE",
      "message": "No inboxes available for this service right now, please try again later",
      "retryable": true,
      "retryAfterSec": 5
    }
  }
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR, SERVICE_DISABLED, INSUFFICIENT_BALANCE, OUT_OF_STOCK, DOMAIN_UNAVAILABLE, WAREHOUSE_UNAVAILABLE, ALL_WAREHOUSES_EXHAUSTED, NO_MAILS_AVAILABLE, QUANTITY_EXCEEDED, WAITING_LIMIT_REACHED, RATE_LIMITED, DUPLICATE_REQUEST, PROVIDER_ERROR, MAINTENANCE
GET/v1/orders/{id}
Bir siparişi kimliğine göre döndürür; şimdiye kadar alınan kodlar (otp[]) dahildir. Sipariş waiting_code durumundayken kodu yakalamak için bu uç noktayı her 3–5 saniyede bir sorgulayın.
otp[] dizisi geliş sırasına göre sıralanır: en eski ilk, EN YENİ SON — son kodu otp[otp.length - 1] ile okuyun. Her çağrıda sistem, hâlâ açık olan siparişler için sağlayıcıyı her kaynağın kendi temposunda (birkaç saniyede bir) kontrol eder — daha sık çağırmak yalnızca kayıtlı verileri döndürür. İlk koddan sonra sorgulamaya devam edin: sonraki kodlar (hizmet birden fazla gönderiyorsa) sipariş süresi içinde ek ücret olmadan otp[] dizisinin sonuna eklenir — sınır ve süre kiralamadan önce gösterilir (offers[] içindeki maxCodes ve fee); sistemin yeni bir kod beklediğinden emin olmak için POST /v1/orders/{id}/next-code çağırın (her kaynakta; yalnızca ücretsiz penceresi dışındaki kaynak 2 ücret alır). Hizmet gelen kutusu başına yalnızca bir koda izin veriyorsa otp[] o kodda durur — yanıtlar normal kalır, hata olmaz. warehouse alanı gelen kutusunu hangi kaynağın verdiğini bildirir (1–4); nextCodeFee ek kodların ücretidir (kaynak 2 ve 3 siparişleri; kaynak 1 ve 4 için null) — bkz. Kaynaklar. 2026-10-02 tarihinden itibaren siparişler ayrıca nextCodeBlocked (true = gelen kutusu artık kod alamaz) ve nextCodeBlockReason alanlarını taşır — nedeni: "email_banned" (e-posta hizmet tarafından kilitlendi — yenisini kiralayın), "activation_gone" (sağlayıcı gelen kutusunu kapattı), "hard_expired" (kod süresi sona erdi), "max_codes" (izin verilen en fazla kod sayısına ulaşıldı), null (engellenmedi / nedeni kaydedilmemiş eski sipariş). Bunlar eklenen alanlardır — mevcut istemcilerde değişiklik gerekmez. Çok sayıda siparişi mi sorguluyorsunuz? Her sipariş için ayrı bir GET yerine çağrı başına en fazla 100 kimliği POST /v1/orders/status adresine gönderin — aynı sipariş nesneleri, istek sınırına yalnızca tek istek.
Parametreler
AdTürZorunluAçıklama
idstringEvetSipariş kimliği (sipariş oluşturulurken dönen orderId)
Örnek
curl "https://otpgmail.net/v1/orders/ORDER_ID" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "orderId": "abc123xyz",
    "service": "ig",
    "domain": "gmail.com",
    "email": "[email protected]",
    "status": "completed",
    "price": 1060,
    "otp": [
      {
        "code": "123456",
        "receivedAt": 1753268500
      },
      {
        "code": "789012",
        "receivedAt": 1753269000
      }
    ],
    "codeDeadlineAt": 1753270000,
    "rentExpiresAt": 1753356400,
    "createdAt": 1753268200,
    "warehouse": 1,
    "nextCodeFee": null,
    "listening": true,
    "listenUntil": 1753270500,
    "nextCodeBlocked": false,
    "nextCodeBlockReason": null
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND
POST/v1/orders/{id}/cancel
Siparişi iptal eder ve fiyatın %100'ünü iade eder. Yalnızca sipariş waiting_code durumundayken VE hiç kod alınmamışken izin verilir.
Kod almış bir sipariş (tek bir kod bile olsa) iptal edilemez veya iade edilemez — bu hem web sitesi hem de API için geçerlidir. rules.cancellable = false olan siparişler (Cointiply gibi kendi stokundan hizmetler) iptal edilemez: gelen kutusu atandıktan sonra iptal ve iade yoktur — iptal çağrısı ORDER_NOT_CANCELLABLE döndürür. Normal hizmetlerin kaynak 3 siparişleri (rules.cancellable = true), kod gelmeden önce diğer siparişler gibi iptal edilebilir.
Parametreler
AdTürZorunluAçıklama
idstringEvetİptal edilecek siparişin kimliği
Örnek
curl -X POST "https://otpgmail.net/v1/orders/ORDER_ID/cancel" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json"
Örnek yanıt
{
  "success": true,
  "data": {
    "orderId": "abc123xyz",
    "service": "ig",
    "domain": "gmail.com",
    "email": "[email protected]",
    "status": "cancelled",
    "price": 1060,
    "otp": [],
    "codeDeadlineAt": 1753270000,
    "rentExpiresAt": 1753356400,
    "createdAt": 1753268200,
    "warehouse": 1,
    "nextCodeFee": null,
    "listening": false,
    "listenUntil": null,
    "nextCodeBlocked": false,
    "nextCodeBlockReason": null
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, ORDER_NOT_CANCELLABLE, PROVIDER_ERROR
POST/v1/orders/{id}/rerent
Kendi stokundan bir hizmetin (provider = "inventory", örn. Cointiply) siparişi için AYNI gelen kutusunu yeniden kiralar: o gelen kutusunda yeni bir alma süresiyle YENİ bir sipariş oluşturur; fiyat eski siparişin rerentPriceVnd değeridir.
Yalnızca eski siparişin canRerent = true olduğu durumda çalışır (o gelen kutusunun en son siparişi; önceki süresi bitmiş veya tüm e-postaları almış). Başarılı olur olmaz ücret alınır — Idempotency-Key gönderin ve yeniden denerken aynısını kullanın; böylece iki kez ücret alınmaz. Yanıt { order, message } biçimindedir; order, GET /v1/orders/{id} ile aynı yapıdadır. Kaynak 2 (2026-10-09'dan itibaren): iptal edilmiş, süresi dolmuş veya bitmiş (gelen kutusu kapalı) bir sipariş — canRerent = true olduğunda çağırın (o e-postanın en son siparişi ve e-postada başka etkin sipariş yok). Sistem AYNI e-postayı YENİ bir sipariş olarak (status = waiting_code) rerentPriceVnd fiyatıyla (şu anda fiyatınızın %100'ü) yeniden açar ve her Kaynak 2 siparişi gibi bir e-posta için 20 dakika bekler — e-posta gelmezse iptal edilir ve %100 iade edilir. E-posta hizmet tarafından kilitlendiyse ⇒ RERENT_EMAIL_BANNED; sağlayıcı artık yeniden açamıyorsa ⇒ RERENT_MAIL_GONE; Kaynak 2 geçici olarak kesintideyse ⇒ PROVIDER_ERROR — üçünde de ücret alınmaz.
Parametreler
AdTürZorunluAçıklama
idstringEvetGelen kutusunun önceki siparişinin kimliği (canRerent = true olan)
Örnek
# Zaman aşımından sonra yeniden denerken AYNI anahtarı tekrar kullanın (yinelenen siparişleri önler)
curl -X POST "https://otpgmail.net/v1/orders/ORDER_ID/rerent" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Idempotency-Key: $(uuidgen)"
Örnek yanıt
{
  "success": true,
  "data": {
    "order": {
      "orderId": "def456uvw",
      "service": "ctp",
      "domain": "icloud.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 3500,
      "otp": [],
      "codeDeadlineAt": 1753273500,
      "rentExpiresAt": 1753273500,
      "createdAt": 1753269000,
      "provider": "inventory",
      "rules": {
        "windowMinutes": 75,
        "maxCodes": 4,
        "cancellable": false,
        "refundOnTimeout": false,
        "rerentRatio": 0.5
      },
      "windowEndsAt": 1753273500,
      "canRerent": false,
      "rerentPriceVnd": 3500,
      "warehouse": 3,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    },
    "message": "Inbox rented again — a new 75-minute message window has started"
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, RERENT_NOT_AVAILABLE, RERENT_EMAIL_BANNED, RERENT_MAIL_GONE, INSUFFICIENT_BALANCE, WAITING_LIMIT_REACHED, RATE_LIMITED, DUPLICATE_REQUEST, PROVIDER_ERROR, MAINTENANCE
POST/v1/orders/{id}/next-code
AYNI gelen kutusunda bir sonraki kodu ister — ilk kodunu almış (status = completed) HER kaynaktaki (warehouse 1–4) siparişler için çalışır. Ücretsizdir; tek istisna, ücretsiz penceresi kapanmış kaynak 2 siparişleridir (nextCodeFee.feePriceVnd > 0): bu durumda ücreti ödemek ve bir kod penceresi daha açmak için confirmFee: true gönderin (nextCodeFee.hardUntil kesin sınırına kadar). Botunuzun kaynağı bilmesi gerekmez: GET /v1/orders/{id} adresini sorgulamaya devam edin — yeni kodlar otp[] dizisinin sonuna eklenir — ve sistemin yeni bir kod beklemesini istediğinizde bu uç noktayı çağırın.
Bu çağrı her kaynakta ne yapar
  • Kaynak 1: sistem, sipariş süresi içinde (rentExpiresAt) her koddan sonra bir sonrakini kendiliğinden bekler — çağrı 200 döner ve hiçbir şeyi değiştirmez; gelen kutusu artık kod alamıyorsa (kod sınırına ulaşıldı, gelen kutusu kapandı, süre doldu) ⇒ nextCodeBlockReason ile birlikte 409.
  • Kaynak 2: gelen kutusunu sağlayıcıda yeniden açar (reordered = true) ve bir e-posta için 20 dakika bekler; ücretsiz pencere içinde ücretsizdir (nextCodeFee.feePriceVnd = 0), pencere dışında confirmFee = true göndermeniz gerekir (eksikse ⇒ 409 NEXT_CODE_FEE_CONFIRM, ücret alınmaz). Ücret yalnızca yeni bir kod gelirse alınmış kalır — 20 dakika içinde kod gelmezse ⇒ otomatik iade. Her koddan sonra sistem bir sonrakini 25 dakika daha kendiliğinden bekler (listening = true, listenUntil).
  • Kaynak 3 (normal hizmetler): kısa bir dinleme süresini yeniden açar, ücretsiz pencere içinde ücretsizdir (nextCodeFee.freeUntil); pencere bitince ⇒ 409 — POST /v1/orders/{id}/rerent kullanın. Cointiply gibi özel envanter hizmetlerinde (rules.cancellable = false) bu çağrı yoktur (409): pencere boyunca her e-posta kendiliğinden görünür.
  • Kaynak 4: siparişi sağlayıcıda yeniden okur ve yeni bir kod bekler, rentExpiresAt zamanına kadar ücretsizdir.
200 = sistem bu sipariş için yeni bir kod bekliyor (listening = true, listenUntil = beklemenin biteceği an; gelen kutusu az önce yeniden açıldıysa reordered = true; ücret alındıysa chargedVnd) ya da çağırdığınız anda yeni bir kod geldi (order.otp içinde zaten var). 409 = yeni bir bekleme açılamadı — error.code değerini okuyun; gelen kutusunun neden başka kod alamadığı order.nextCodeBlockReason içindedir (GET /v1/orders/{id}). Henüz ilk kodunu bekleyen sipariş (waiting_code) ⇒ 409, şimdilik çağırmanıza gerek yok. Ücretli çağrılarla bir Idempotency-Key gönderin (yeniden denerken aynısını kullanın; böylece iki kez ücret alınmaz). Sağlayıcıya ulaşılamazsa ⇒ 502 PROVIDER_ERROR, daha sonra tekrar deneyin. Bu çağrının 409 hata kodları: NEXT_CODE_FEE_CONFIRM (kaynak 2 ücret istiyor — confirmFee: true ile yeniden çağırın), EMAIL_BANNED (e-posta hizmet tarafından kilitlendi — yenisini kiralayın; error.details.blockReason = "email_banned"), ORDER_EXPIRED (süre doldu, gelen kutusu kapandı, kod sınırına ulaşıldı ya da hizmette "sonraki kod" yok — neden order.nextCodeBlockReason içinde), ORDER_NOT_CANCELLABLE (sipariş henüz ilk kodunu almadı). Bu çağrıdaki her 409'u "başka kod yok" sayan botlar değişiklik yapmadan çalışmaya devam eder. refresh: true (kaynak 2): önce yeni e-posta kontrol edilir (az önce gelen teslim edilir, yeniden açılmaz), sonra gelen kutusu sağlayıcıda yeniden açılır — ücretsiz pencere içinde bekleme 20 dakika yeniden başlar; pencere dışında bekleme bitiş zamanı (listenUntil) aynı kalır ve ücret alınmaz. Yanıta refreshed (true = şimdi yeniden açıldı) ve refreshAvailableAt (unix saniye; bu andan önce yenileme yalnızca e-posta kontrol eder; null = hemen yapılabilir) eklenir. Diğer kaynaklar: etkisi yok (refreshed = false). refresh gönderilmezse çağrı tam olarak eskisi gibi çalışır.
Parametreler
AdTürZorunluAçıklama
idstringEvetSipariş kimliği (orderId) — herhangi bir kaynak
confirmFeebooleanHayırtrue = başka bir kod penceresi açmak için nextCodeFee.feePriceVnd tutarını ödemeyi kabul edersiniz. feePriceVnd = 0 iken gerekmez.
refreshbooleanHayırtrue = kaynak 2, sipariş yeni kod bekliyor (listening = true) ama kod gelmiyor: gelen kutusunu sağlayıcıda hemen yeniden aç (beklemeyi yenile) — eski bekleme sağlayıcı tarafında e-posta almayı bırakmış olabilir. Ücretsiz; sipariş başına en fazla 5 sn'de bir. Sipariş beklemiyorsa ⇒ normal çağrıyla aynı.
Örnek
# Ücretsiz (nextCodeFee null veya feePriceVnd = 0 — ücretsiz penceresi bitmiş kaynak 2 hariç her kaynak): confirmFee gerekmez
curl -X POST "https://otpgmail.net/v1/orders/ORDER_ID/next-code" \
  -H "Authorization: Bearer og_xxx..."

# Ücretsiz penceresi bitmiş kaynak 2: nextCodeFee.feePriceVnd tutarını ödemek için confirmFee = true gönderin
curl -X POST "https://otpgmail.net/v1/orders/ORDER_ID/next-code" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"confirmFee":true}'
Örnek yanıt
{
  "success": true,
  "data": {
    "order": {
      "orderId": "ghi789rst",
      "service": "dr",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "completed",
      "price": 350,
      "otp": [
        {
          "code": "482913",
          "receivedAt": 1753268300
        }
      ],
      "codeDeadlineAt": 1753269700,
      "rentExpiresAt": 1753354200,
      "createdAt": 1753267800,
      "warehouse": 2,
      "nextCodeFee": {
        "feePriceVnd": 0,
        "freeUntil": 1753311000,
        "hardUntil": 1753354200,
        "paidPct": 50,
        "freeHours": 6
      },
      "listening": true,
      "listenUntil": 1753269500,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    },
    "message": "Another code window is open — waiting for a new code",
    "listening": true,
    "listenUntil": 1753269500,
    "reordered": true
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, VALIDATION_ERROR, NEXT_CODE_FEE_CONFIRM, INSUFFICIENT_BALANCE, EMAIL_BANNED, ORDER_EXPIRED, ORDER_NOT_CANCELLABLE, PROVIDER_ERROR, DUPLICATE_REQUEST, MAINTENANCE

Çok sayıda siparişin durumu: tek çağrıda

Çok sayıda gelen kutusu kiralayan bayiler ve botlar her sipariş için ayrı bir GET /v1/orders/{id} göndermemeli: POST /v1/orders/status aynı sipariş nesneleriyle çağrı başına en fazla 100 sipariş okur, GET /v1/orders ise siparişlerinizi kayıtlı verilerden listeler.
  • POST /v1/orders/status ile her 3–5 saniyede bir sorgulayın, çağrı başına en fazla 100 sipariş kimliği — her çağrı istek sınırınıza tek istek olarak sayılır.
  • Her çağrıda sistem, listedeki açık siparişlerden en fazla 20 tanesi için sağlayıcıyı kontrol eder (önce ilk kodunu bekleyenler, sonra en uzun süredir kontrol edilmeyenler) ve kalanları kayıtlı verilerden döndürür; onlar sonraki çağrılarda kontrol edilir. Bir çağrı yaklaşık 3 saniye içinde yanıt verir.
  • Sonuçlanan siparişi listenizden çıkarın: cancelled (iade edildi) ya da artık kod gerekmiyorsa completed.
  • Var olmayan ya da başka bir hesaba ait kimlikler missing içinde döner (404 yok) — onları da çıkarın.
  • Yeniden başlattıktan sonra açık tüm siparişleri GET /v1/orders?status=waiting_code ile geri alın (nextCursor'ı izleyin), ardından POST /v1/orders/status ile sorgulamaya devam edin.
POST/v1/orders/status
Tek çağrıda siparişlerinizden en fazla 100 tanesini döndürür. Her öğe, o sipariş için GET /v1/orders/{id} ne döndürüyorsa tam olarak odur (status, alınan tüm kodlarla otp[], warehouse…). Açık siparişlerin çoğunu aynı anda sorgulamak için kullanın.
data, ids sırasını korur; yinelenen kimlikler yok sayılır. Var olmayan ya da başka bir hesaba ait kimlikler missing içinde listelenir (404 yok). Açık siparişler için sistem, sağlayıcıyı GET /v1/orders/{id} gibi kontrol eder, ancak çağrı başına en fazla 20 sipariş için — önce ilk kodunu bekleyenler, sonra en uzun süredir kontrol edilmeyenler — diğerlerini kayıtlı verilerden döndürür (sonraki çağrılarda kontrol edilirler); bir çağrı yaklaşık 3 saniye içinde yanıt verir. Kaç kimlik içerirse içersin bir çağrı, istek sınırına tek istek olarak sayılır. 100'den fazla kimlik, boş liste veya metin olmayan kimlikler ⇒ 400 VALIDATION_ERROR.
Parametreler
AdTürZorunluAçıklama
idsstring[]EvetSipariş kimlikleri (orderId) — çağrı başına 1 ile 100 arası
Örnek
# Beklediğiniz siparişlerin kimlikleri (POST /v1/orders'tan gelen orderId) — çağrı başına en fazla 100
curl -X POST "https://otpgmail.net/v1/orders/status" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -d '{"ids":["ORDER_ID_1","ORDER_ID_2"]}'
Örnek yanıt
{
  "success": true,
  "data": [
    {
      "orderId": "abc123xyz",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "completed",
      "price": 1060,
      "otp": [
        {
          "code": "123456",
          "receivedAt": 1753268500
        }
      ],
      "codeDeadlineAt": 1753270000,
      "rentExpiresAt": 1753356400,
      "createdAt": 1753268200,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    },
    {
      "orderId": "jkl012mno",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270001,
      "rentExpiresAt": 1753356401,
      "createdAt": 1753268201,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    }
  ],
  "missing": [
    "zzz999qqq"
  ]
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR, RATE_LIMITED
GET/v1/orders
Siparişlerinizi en yeniden eskiye, yalnızca kayıtlı verilerden listeler — yeni kodlar için sağlayıcıya sormaz (bunu POST /v1/orders/status yapar). Duruma ve oluşturulma zamanına göre filtreleyin; nextCursor ile sayfalayın.
Sonraki sayfa için nextCursor değerini cursor olarak gönderin; nextCursor = null ⇒ son sayfa. Aynı saniyede çok sayıda sipariş oluşturulmuş olsa bile sayfalar bir siparişi asla tekrarlamaz ya da atlamaz. İç durumlar hiçbir zaman listelenmez (yalnızca waiting_code, completed, cancelled ve queued). Botunuz yeniden başladıktan sonra: GET /v1/orders?status=waiting_code&limit=200, nextCursor'ı izleyin, ardından bu siparişleri POST /v1/orders/status ile sorgulayın.
Parametreler
AdTürZorunluAçıklama
statusstringHayırYalnızca bu durum: waiting_code | completed | cancelled | queued (gönderilmezse ⇒ hepsi)
sincenumberHayırYalnızca bu unix zamanında (saniye) veya sonrasında oluşturulan siparişler
limitnumberHayırSayfa başına sipariş: 1–200 (varsayılan 50)
cursorstringHayırÖnceki sayfanın nextCursor değeri, değiştirmeden
Örnek
# Yeniden başlattıktan sonra: hâlâ kod bekleyen tüm siparişleri sayfa sayfa toplayın
curl "https://otpgmail.net/v1/orders?status=waiting_code&limit=200" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": [
    {
      "orderId": "jkl012mno",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270001,
      "rentExpiresAt": 1753356401,
      "createdAt": 1753268201,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    },
    {
      "orderId": "abc123xyz",
      "service": "ig",
      "domain": "gmail.com",
      "email": "[email protected]",
      "status": "waiting_code",
      "price": 1060,
      "otp": [],
      "codeDeadlineAt": 1753270000,
      "rentExpiresAt": 1753356400,
      "createdAt": 1753268200,
      "warehouse": 1,
      "nextCodeFee": null,
      "listening": false,
      "listenUntil": null,
      "nextCodeBlocked": false,
      "nextCodeBlockReason": null
    }
  ],
  "nextCursor": "1753268200:abc123xyz"
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR, RATE_LIMITED

Kaynaklar

Her offers[] kaydı bir tekliftir = (hizmet, kaynak, gelen kutusu türü). Yalnızca şu anda satış yapan kaynaklar listelenir; geçici olarak stoğu tükenen bir kaynak stock = 0 ile listede kalır. Kaynak numaraları sabittir: 1, 2, 3, 4 — sipariş oluştururken aynı numarayı warehouse parametresinde gönderin.
Mevcut istemcilerde değişiklik gerekmez. warehouse belirtilmezse ⇒ eskisiyle aynı davranış (kaynak 1: 25 dakikalık bekleme; hizmet birden fazla kod gönderiyorsa ek kodlar 24 saatlik sipariş süresi içinde otomatik gelir); 0 gönderirseniz ⇒ stokta olan en ucuz kaynak; 99 gönderirseniz ⇒ otomatik kaynak, biri tükenince sonrakine geçer (hemen aşağıya bakın); mevcut her alan olduğu gibi kalır — yalnızca yeni alanlar eklenir (offers[], warehouse, nextCodeFee, listening, nextCodeBlocked…).
Otomatik kaynak: warehouse = 99 (sık tükenen hizmetler için önerilir)
"warehouse": 99 gönderin; sistem stokta olan en ucuz kaynaktan kiralar; o kaynağın stoğu tükenmişse veya hata veriyorsa aynı çağrı içinde bir sonrakine geçer. Facebook ve Instagram gibi sık tükenen hizmetler için idealdir — botunuzun artık offers[] dizisini okuyup kaynak kaynak yeniden denemesi gerekmez.
  • Deneme sırası: fiyat düşükten yükseğe (örn. 1.500 → 1.600 → 1.700 VND); fiyatlar eşitse ⇒ önce düşük kaynak numarası.
  • Stoğu sıfır bildiren kaynaklar (offers[] içinde stock = 0) hiç çağrılmaz — zaman kaybı olmaz.
  • Mevcut kaynağın stoğu tükenmişse veya hata veriyorsa sonrakine geçer (OUT_OF_STOCK, NO_MAILS_AVAILABLE, WAREHOUSE_UNAVAILABLE, PROVIDER_ERROR).
  • Diğer hatalar, sonraki kaynak denenmeden hemen döndürülür: INSUFFICIENT_BALANCE, WAITING_LIMIT_REACHED, QUANTITY_EXCEEDED, MAINTENANCE, SERVICE_DISABLED, DOMAIN_UNAVAILABLE…
  • quantity > 1: ilk kaynak yetmezse kalanı sonraki kaynaktan gelir — siparişler birkaç kaynağa yayılabilir; her sipariş, onu veren kaynağın warehouse ve price değerlerini taşır (ve o kaynağın kod kurallarına tabidir).
  • Her kaynak denendiği halde hiç gelen kutusu kiralanamadıysa ⇒ ALL_WAREHOUSES_EXHAUSTED (HTTP 409, ücret alınmaz) — daha sonra tekrar deneyin. Yalnızca bazı gelen kutuları kiralandıysa yine de bu siparişlerle 200 alırsınız.
Örnek: warehouse = 99 ile Facebook Gmail kiralama
# warehouse: 99 — stokta olan en ucuz kaynak; stok yok veya hata varsa ⇒ otomatik olarak sonraki kaynak
curl -X POST "https://otpgmail.net/v1/orders" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"service":"fb","quantity":1,"domain":"gmail.com","warehouse":99}'
offers[] alanları
AlanTürAçıklama
warehouse1 | 2 | 3 | 4Kaynak numarası: 1, 2, 3 veya 4.
domainstringTeklifin gelen kutusu türü: gmail.com, icloud.com veya gmx.com (ek alan adı — yalnızca bazı hizmetlerde, şu anda Pokemon).
pricenumberBu kaynaktan bir gelen kutusunun fiyatı (VND).
stocknumberKalan gelen kutuları. 0 = stok yok — kaynak 1 veya 2'den kiralamak WAREHOUSE_UNAVAILABLE döndürür; kaynak 4 yine de denenir (kaynakları 0 bildirse de çoğu zaman teslim eder) ve hiçbir şey yoksa OUT_OF_STOCK döndürür.
maxCodesnumber | nullBir gelen kutusunun alabileceği en fazla kod; null = sınır yok / bilinmiyor (bkz. fee).
rulesobject | nullKaynak 3 için pencere kuralları (windowMinutes, maxCodes, cancellable, refundOnTimeout, rerentRatio); kaynak 1, 2 ve 4 için null.
feeobject | nullEk kod penceresi: kiralamadan itibaren freeHours ücretsiz saat, sonrasında her uzatma kira bedelinin %paidPct kadarıdır, kiralamadan itibaren en fazla maxHours saate kadar (null = sınır yok). fee = null: ücret yok — hizmet birden fazla kod gönderiyorsa ek kodlar sipariş süresi içinde ücretsizdir (maxCodes değerine kadar), kaynak 1'deki gibi.
isDefaultbooleanStokta olan en ucuz kaynak için true (eşitlikte ⇒ düşük kaynak numarası) — warehouse = 0 ile kullanılan kaynak ve 99 ile denenen ilk kaynak.
Kaynağa göre kurallar
KuralKaynak 1Kaynak 2Kaynak 3Kaynak 4
İlk kod için bekleme25 dakika20 dakika25 dakika ¹En fazla 25 dakika (bazı tedarikçilerde daha kısa — gerçek son an siparişin codeDeadlineAt değeridir)
Kod gelmezseOtomatik iptal, %100 iadeOtomatik iptal, %100 iadeOtomatik iptal, %100 iade ¹Otomatik iptal, %100 iade
Kod gelmeden iptalEvetEvetEvet ¹Evet
Gelen kutusu başına kodmaxCodes değerine göreLimit yokLimit yok ¹maxCodes değerine göre (genellikle null = sınır yok; bazı tekliflerde 1)
Ek kodlarHizmet daha fazla kod gönderiyorsa 24 saatlik sipariş süresi içinde ek ücret yok; otomatik (ek çağrı gerekmez). Gelen kutusu genellikle son koddan sonra yaklaşık 25 dakika açık kalır.fee.freeHours saat ücretsiz (şu anda Gmail 6 saat, iCloud 12 saat); sonrasında her uzatma, next-code ile fiyatın %fee.paidPct kadarıdır, fee.maxHours değerine kadar (Gmail 24 saat, iCloud 10 gün)24 saat boyunca ek ücret yok; sonrasında aynı gelen kutusunu yeniden kiralayın (rerent), fiyatın %50'siKaynak 1 gibi 24 saatlik sipariş süresi içinde ek ücret yok — yeni kodlar siparişi okuduğunuzda görünür; next-code siparişi hemen yeniden okur.
¹ Yalnızca kendi stokundan satılan hizmetler (örn. Cointiply: provider = "inventory", rules.cancellable = false) rules alanını izler: rules.windowMinutes dakika içinde en fazla rules.maxCodes e-posta, iptal yok ve e-posta gelmeden süre dolarsa iade yok.
nextCodeFee — ek kodların ücreti (kaynak 2 ve 3 siparişleri)
GET /v1/orders/{id} yanıtına ve her sipariş yanıtına dahildir; kaynak 1 ve 4 siparişlerinde null (ek kodlar ücretsizdir). Kaynak 2: başka bir koda ihtiyaç duyduğunuzda POST /v1/orders/{id}/next-code çağrısı yapın — feePriceVnd 0'dan büyükse confirmFee = true göndermeniz gerekir. Kaynak 3 (normal hizmetler): ücretsiz pencere bittiğinde feePriceVnd, aynı gelen kutusunu yeniden kiralamanın fiyatıdır (rerent).
AlanTürAçıklama
feePriceVndnumbernext-code şimdi çağrılırsa alınacak tutar; 0 = ücretsiz pencere halen açık.
freeUntilnumber | nullMevcut ücretsiz pencerenin bitişi (unix saniye).
hardUntilnumber | nullKesin sınır (unix saniye) — bu andan sonra başka kod gelmez.
paidPctnumberHer ek pencere için alınan kira bedeli yüzdesi.
freeHoursnumberBir kod penceresinin ücretsiz saat sayısı (kaynak 2: Gmail 6, iCloud 12; kaynak 3: 24).
Örnek: kaynakları listeleyin, sonra birinden kiralayın
# warehouse: 0 | 1–4 | 99 (isteğe bağlı — eskisi gibi kaynak 1 için belirtmeyin; 0 = stokta olan en ucuz kaynak; 99 = otomatik, bir kaynak tükenince sonrakine geçer; bkz. GET /v1/services içindeki offers[])
curl -X POST "https://otpgmail.net/v1/orders" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"service":"dr","quantity":1,"domain":"gmail.com","warehouse":2}'
Örnek kaynak 2 siparişi (GET /v1/orders/{id})
{
  "success": true,
  "data": {
    "orderId": "ghi789rst",
    "service": "dr",
    "domain": "gmail.com",
    "email": "[email protected]",
    "status": "completed",
    "price": 350,
    "otp": [
      {
        "code": "482913",
        "receivedAt": 1753268300
      }
    ],
    "codeDeadlineAt": 1753269700,
    "rentExpiresAt": 1753354200,
    "createdAt": 1753267800,
    "warehouse": 2,
    "nextCodeFee": {
      "feePriceVnd": 175,
      "freeUntil": 1753289400,
      "hardUntil": 1753354200,
      "paidPct": 50,
      "freeHours": 6
    },
    "listening": false,
    "listenUntil": null,
    "nextCodeBlocked": false,
    "nextCodeBlockReason": null
  }
}

Toplu kiralama (toplu siparişler)

Toplu siparişler web'de (Toplu kiralama sayfası) satın alınır — API ile toplu siparişleri listeleyip kodları okuyabilirsiniz. E-posta alan adı kaynağı belirler: Gmail = Kaynak 1, iCloud = Kaynak 3 (özel gelen kutuları).
  • Toplu sipariş, satın almadan itibaren 24 saat saklanır — bu sürede kodları ücretsiz okuyun, kod sayısında sınır yoktur.
  • Kod almayan gelen kutuları için iade yapılmaz; yalnızca adetteki eksiklik (otomatik olarak) iade edilir.
  • Kaynak 1 (Gmail): her gelen kutusunun bir proxyUrl alanı vardır — bir GET, API anahtarı olmadan {"status":1,"code":"482913","all_codes":[...]} döndürür (bağlantının kendisi gizli bilgidir — özel tutun). Aşağıdaki kod uç noktası da çalışır.
  • Kaynak 3 (iCloud): proxyUrl = null — kodları aşağıdaki uç noktayla okuyun veya readUrl adresini (web sayfası) açın. Her gelen kutusu o hizmet için hesabınıza bağlıdır; süre dolduktan sonra yine de web'de yeniden kiralayabilirsiniz.
  • Ayıklanabilir kodu olmayan e-postalar (karşılama e-postaları, bültenler…) isRaw: true ile code içinde aynen gelir (HTML veya metin, en fazla 20.000 karakter).
Toplu siparişteki bir gelen kutusunun alanları (mails[])
AlanTürAçıklama
idnumberGelen kutusu kimliği — kod uç noktasının {mailId} parametresi
emailstringE-posta adresi
urlstringKaynak 1: = proxyUrl · kaynak 3: = readUrl (eski betikler / dışa aktarma dosyaları için korunur)
proxyUrlstring | nullKaynak 1: giriş gerektirmeyen kod bağlantısı · kaynak 3: null
readUrlstringToplu siparişin kodlarını okumak için web sayfası
codeCountnumberAlınan kod sayısı
lastCodestring | nullEn yeni kod (ham e-posta: ilk 300 karakter — tam metin kod uç noktasındadır)
lastIsRawbooleantrue = en yeni kod ham bir e-postadır
checkedAtnumber | nullSistemin bu gelen kutusu için sağlayıcıyı en son kontrol ettiği an (unix saniye; null = hiç)
GET/v1/batches
Toplu siparişleriniz, en yeniden eskiye (page / pageSize ile sayfalanır, en fazla 100). Her toplu sipariş warehouse (1 = Gmail, 3 = iCloud), status (active | expired | failed), expiresAt, codeCount ve readUrl alanlarına sahiptir.
Parametreler
AdTürZorunluAçıklama
pagenumberHayırSayfa (varsayılan 1)
pageSizenumberHayırSayfa başına toplu sipariş (varsayılan 20, en fazla 100)
Örnek
curl "https://otpgmail.net/v1/batches?page=1&pageSize=20" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "k3v9m2x7q1w8e5r4",
        "serviceCode": "lf",
        "serviceName": "Tiktok",
        "domain": "icloud.com",
        "warehouse": 3,
        "status": "active",
        "countRequested": 3,
        "countReceived": 3,
        "countDuplicate": 0,
        "countCharged": 3,
        "unitPriceVnd": 600,
        "quotedVnd": 1800,
        "chargedVnd": 1800,
        "refundVnd": 0,
        "holdHours": 24,
        "expiresAt": 1753354200,
        "createdAt": 1753267800,
        "readUrl": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
        "codeCount": 1,
        "rerentPriceVnd": null
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 20
  }
}
Olası hatalar: UNAUTHORIZED
GET/v1/batches/{id}
mails[] dizisiyle birlikte tek bir toplu sipariş — kodlarını okumak için her gelen kutusunun id değerini alın.
Gmail toplu siparişleri (kaynak 1): her gelen kutusunun proxyUrl değeri betiklerinizde eskisi gibi çalışır. iCloud toplu siparişleri (kaynak 3): proxyUrl = null, kodları aşağıdaki uç noktayla okuyun. Süresi dolmuş iCloud toplu siparişleri rerentPriceVnd değerini taşır — bir gelen kutusunu tek tek yeniden kiralamanın fiyatı (web'de yapılır).
Parametreler
AdTürZorunluAçıklama
idstringEvetToplu sipariş kimliği (Toplu kiralama sayfasında ve readUrl içinde görünür)
Örnek
curl "https://otpgmail.net/v1/batches/BATCH_ID" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "id": "k3v9m2x7q1w8e5r4",
    "serviceCode": "lf",
    "serviceName": "Tiktok",
    "domain": "icloud.com",
    "warehouse": 3,
    "status": "active",
    "countRequested": 3,
    "countReceived": 3,
    "countDuplicate": 0,
    "countCharged": 3,
    "unitPriceVnd": 600,
    "quotedVnd": 1800,
    "chargedVnd": 1800,
    "refundVnd": 0,
    "holdHours": 24,
    "expiresAt": 1753354200,
    "createdAt": 1753267800,
    "readUrl": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
    "codeCount": 1,
    "rerentPriceVnd": null,
    "mails": [
      {
        "id": 812,
        "email": "[email protected]",
        "url": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
        "proxyUrl": null,
        "readUrl": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
        "fresh": true,
        "codeCount": 1,
        "lastCode": "482913",
        "lastCodeAt": 1753268500,
        "lastIsRaw": false,
        "checkedAt": 1753268507
      }
    ]
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND
GET/v1/batches/{id}/mails/{mailId}/codes
Bir toplu siparişteki tek bir gelen kutusunun kodlarını okuyun: gelen kutusunun sırası geldiyse sistem sağlayıcıyı kontrol eder, ardından alınan HER kodu en eskiden başlayarak döndürür — en yeni kod codes[] içinde sondadır.
Beklerken her 5–10 saniyede bir sorgulayın (daha sık çağırmak yalnızca saklanan veriyi döndürür — polledAt değişmez). Ayıklanabilir kodu olmayan e-postalar, isRaw: true ile code içinde aynen gelir. Süresi dolmuş toplu siparişler saklanan kodlarını yine döndürür ancak artık kontrol edilmez.
Parametreler
AdTürZorunluAçıklama
idstringEvetToplu sipariş kimliği
mailIdnumberEvetGelen kutusu kimliği (mails[].id)
poll0 | 1Hayır0 = yalnızca saklanan kodları oku, sağlayıcıyı kontrol etme (varsayılan 1)
Örnek
# Beklerken her 5–10 saniyede bir yeniden çağırın; en yeni kod codes[] içinde sondadır
curl "https://otpgmail.net/v1/batches/BATCH_ID/mails/MAIL_ID/codes" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "mailId": 812,
    "codes": [
      {
        "code": "482913",
        "receivedAt": 1753268500,
        "isRaw": false
      }
    ],
    "polledAt": 1753268507,
    "mail": {
      "id": 812,
      "email": "[email protected]",
      "url": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
      "proxyUrl": null,
      "readUrl": "https://otpgmail.net/app/batch/k3v9m2x7q1w8e5r4",
      "fresh": true,
      "codeCount": 1,
      "lastCode": "482913",
      "lastCodeAt": 1753268500,
      "lastIsRaw": false,
      "checkedAt": 1753268507
    }
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, RATE_LIMITED

Buy live Gmail accounts (2 warehouses)

Buy short-lived Gmail accounts outright: you are charged when you order and the accounts arrive within seconds. There are two mail-shop warehouses (numbered separately from the OTP-rental warehouses 1–4), each with ONE price for any quantity. Prices returned by the API are YOUR account's prices (custom price if the admin set one) — exactly what you are charged.
Warehouses
WarehouseEach account deliversDefault priceStock
1gm_cookieemail · password · cookies · inboxUrl (inbox link) · inboxJsonUrl (emails as JSON) · twoFaUrl (2FA link — just the 6 digits)3,300 VNDA number — published by the source, refreshed every minute. The source checks that accounts are live at purchase time, so you may get fewer — the shortfall is refunded (a partial order; warehouse 99: the rest goes to the next warehouse)
2gm_loginemail · password · loginUrl (quick login link — open it in a desktop browser) · otpUrl (Vinted OTP link — when delivers lists it)6,000 VNDA REFERENCE number from a source sharing the same stock (refreshed every minute; null when it cannot be read) — may be off by a few, never blocks a purchase; a shortfall becomes a partial order with the rest refunded
99As the warehouse that supplied each account (items[].warehouse)Price of the cheapest warehouse on sale (auto.priceVnd)Buys the cheapest warehouse first (auto.order); if it runs out midway the rest goes to the next warehouse at that warehouse's price (the difference is charged — refunded instead if your balance is short); every warehouse out ⇒ MAILSHOP_OUT_OF_STOCK, nothing charged
Kaynak 1 hesaplarına giriş (kurtarma e-postası yok)
  • Kaynak 1 (gm_cookie) hesapları kurtarma e-postası olmadan gelir — e-posta, şifre, çerezler ve gelen kutusu bağlantısını (inboxUrl / inboxJsonUrl) alırsınız, fazlasını değil.
  • Önerilen giriş yolu: çerezleri içe aktarın (cookies, JSON) — bir çerez içe aktarma eklentisiyle ya da antidetect tarayıcınızın çerez içe aktarma özelliğiyle — ardından Gmail'i açın: oturum zaten açıktır, genellikle şifre sorulmaz ve doğrulama istenmez.
  • Yalnızca kodlara veya e-postalara mı ihtiyacınız var? Bunları inboxUrl (web sayfası) veya inboxJsonUrl (JSON) ile okuyun — API anahtarı ve Google girişi gerekmez.
  • Yeni bir cihazda veya IP'de şifreyle giriş yapmak Google'ın doğrulama istemesine (kurtarma e-postası, telefon veya kod) yol açabilir — bu hesaplarda bunu geçecek hiçbir şey yoktur; bunun yerine çerezleri veya gelen kutusu bağlantısını kullanın.
  • Yeniden mi satıyorsunuz? Müşterilerinize çerezleri ve gelen kutusu bağlantısını verin — .txt indirmesi (GET /v1/mail-shop/orders/{id}/download) tek satırda email|password|cookies|inboxUrl içerir — ve onlara şifreyle değil çerezlerle giriş yapmalarını söyleyin.
  • Kaynak 2 (gm_login) hesapları bunun yerine hızlı giriş bağlantısıyla (loginUrl) gelir — giriş yapmak için bağlantıyı masaüstü tarayıcıda açın.
3 steps
  1. See warehouses & prices: GET /v1/mail-shop/products ⇒ products[] (per warehouse: priceVnd, stock, available, maxQty) + auto (warehouse 99: order, priceVnd). To see the total first, call GET /v1/mail-shop/quote.
  2. Buy: POST /v1/mail-shop/orders with {"warehouse": 1 | 2 | 99, "quantity": N} + header Idempotency-Key (a new UUID per purchase). The response is the order, usually already completed with items[].
  3. Get the accounts: read items[] (table below) or download the TXT GET /v1/mail-shop/orders/{id}/download. status = pending ⇒ poll GET /v1/mail-shop/orders/{id} every 5 seconds until completed / partial / failed.
# 1) warehouses, your prices, stock
curl "https://otpgmail.net/v1/mail-shop/products" -H "Authorization: Bearer og_xxx..."

# 2) buy (warehouse 1 | 2 | 99) — a NEW Idempotency-Key per purchase
curl -X POST "https://otpgmail.net/v1/mail-shop/orders" \
  -H "Authorization: Bearer og_xxx..." -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" --max-time 60 \
  -d '{"warehouse":99,"quantity":2}'

# 3) status "pending"? read the order again (or download the .txt)
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID" -H "Authorization: Bearer og_xxx..."
Fields of an account (items[])
AlanTürAçıklama
lineNonumberPosition in the order (1, 2, …) — the {lineNo} of the inbox endpoints
warehouse1 | 2Warehouse that supplied this account
emailstringGmail address
passwordstringPassword
recoverystring?Recovery email — only when the source provides one; warehouse 1 (gm_cookie) accounts have NONE (sign in with the cookies, see the sign-in notes above)
cookiesstring | nullWarehouse 1: login cookies (JSON)
inboxUrlstring | nullWarehouse 1: inbox page without an API key (https://otpgmail.net/mail/{code}); null = link turned off
inboxJsonUrlstring | nullWarehouse 1: the same link + ?json ⇒ emails as JSON (section below)
twoFaUrlstring | nullWarehouse 1: the 2FA LINK (https://otpgmail.net/2fa/{code} — same code + expiry as inboxUrl): GET / open it in a browser ⇒ JUST the 6-digit 2FA code (section below). null = link turned off. The .txt file has this column when downloaded with ?twofa=1
inboxLinkExpiresAtnumber | nullWarehouse 1: when the link expires (unix seconds); null = no limit
loginUrlstring | nullWarehouse 2: quick login link
otpUrlstring | nullWarehouse 2: the account's Vinted OTP link — open it in a browser to see the code, ?json ⇒ JSON (section below). null = this account has no link
otpService"vinted" | nullWarehouse 2: the service of otpUrl
rawLinestringThe whole account on one line (cookies compacted) — copy it as is
Read the inbox as JSON (inboxJsonUrl)
GET {inboxJsonUrl} (= inboxUrl + ?json) returns the same JSON as GET /api/mailbox/{code}: email, letters[] (≤ max latest emails: from, subject, receivedAt, code — extracted code / link, content — sanitized HTML), total, etag, nextAt. No API key needed (the code in the link is the key — keep it private), CORS is open. Add &max=20|50|100|200 for more emails (default 10), &etag={previous etag} ⇒ unchanged emails come back as empty letters + unchanged: true. Reading one link faster than every 10 seconds ⇒ 429 (retryAfter); link off / wrong / expired ⇒ 404; account locked ⇒ 410.
curl "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d?json&max=20"
{
  "success": true,
  "data": {
    "email": "[email protected]",
    "letters": [
      {
        "key": "h:9f2c4e1a7b3d5c80",
        "from": "Instagram [email protected]",
        "subject": "350038 is your Instagram code",
        "receivedAt": 1760000520,
        "code": "350038",
        "content": "<html><body><p>Enter this confirmation code in the app: 350038</p></body></html>"
      }
    ],
    "max": 10,
    "total": 8,
    "fetchedAt": 1760000530,
    "cached": false,
    "etag": "f1c2a9d4e0b37a65",
    "unchanged": false,
    "nextAt": 1760000540,
    "expiresAt": 1762592400,
    "serverTime": 1760000530
  }
}
Read the Vinted OTP code (otpUrl)
A warehouse-2 account with otpUrl ⇒ open it in a browser to see the latest Vinted code (the page refreshes itself); GET {otpUrl}?json returns {status, code, service, email, checkedAt, retryAfter}: status = waiting (no code yet — ask again after retryAfter seconds) · ok (code = the latest code) · dead (codes can no longer be read for this account) · error (temporarily unreadable — ask again). No API key needed (the code in the link is the key — keep it private), CORS is open; the server reads the source at most every few seconds per account; more than 120 calls / minute / IP ⇒ 429.
curl "https://otpgmail.net/api/mail-shop/otp/p3x9k2m7q1w8e5r4.2.Zx8Kq2Lm4Np6Rt0Vw3Yb5c?json"
{
  "success": true,
  "data": {
    "status": "ok",
    "code": "4829",
    "service": "vinted",
    "email": "[email protected]",
    "checkedAt": 1760000530,
    "retryAfter": 5
  }
}
The 2FA code (twoFaUrl)
Some warehouse-1 accounts have 2-step verification (2FA) on — a password sign-in makes Google ask for a 6-digit code. GET {twoFaUrl} (or open it in a browser) returns text/plain with JUST the current 6 digits (no newline), a Refresh header = seconds until the next code + 1 (browsers reload by themselves), Cache-Control: no-store, open CORS — you can hand the link to your customers. Account without 2FA ⇒ 404 no 2fa; wrong / off / expired link ⇒ 404 not found; locked account ⇒ 410 gone; too fast / source hiccup ⇒ 429 / 502 retry (Retry-After header). With an API key: GET /v1/mail-shop/orders/{id}/items/{lineNo}/2fa ⇒ {none, code, expiresIn}. The server caches the code until it expires. The .txt file (GET /v1/mail-shop/orders/{id}/download): add ?twofa=1 ⇒ a last twoFaUrl column (off by default — the old layout is unchanged).
curl "https://otpgmail.net/2fa/Q7xK2mP9vL4tR8wN3cB6yH1d"
# 424819
Order statuses
DurumAçıklama
pendingBeing delivered — accounts that arrived are in items[]; poll again in 5 seconds
completedFully delivered. Final.
partialDelivered short — the shortfall was refunded (refundVnd; message = the reason + the source's own words when it gave any). Final.
failedNothing delivered — fully refunded (message as above). Final.
refundedRefunded by an admin (refundVnd). Final.
Rules
  • Money: chargedVnd = Σ route[].quantity × unitPriceVnd (a 99 order split across warehouses ⇒ two legs in route). Shortfalls are refunded automatically (refundVnd). Delivered accounts are not refunded — the only warranty is the warehouse's terms (read them first).
  • Idempotency-Key is required (400 without it): retrying with the SAME key after a timeout returns the same order and charges nothing more; a new key buys again. Use a client timeout of at least 60 seconds.
  • Limits: at most 500 accounts per order (and the warehouse's maxQty), 10 purchases per minute for your account (web + API share it), 180 inbox reads per hour. Above ⇒ 429 RATE_LIMITED.
  • Common errors: MAILSHOP_OUT_OF_STOCK 409 (details.stock = how many you can buy now) · MAILSHOP_QTY_LIMIT 400 (details.max) · INSUFFICIENT_BALANCE 402 · MAILSHOP_DISABLED 503 (warehouse / section paused) · MAILSHOP_SUPPLIER_ERROR 502 (the source refused at once — a failed order was recorded and refunded, details.orderId) · VALIDATION_ERROR 400 (warehouse not 1 | 2 | 99, warehouse and product disagree, missing Idempotency-Key…).
  • Terms (warranty only for the first sign-in within 2 hours, accounts last ~6–24 hours) are in each warehouse's terms; the API does not ask you to accept them (the web asks once). API orders show up in your web history (channel = api) and vice versa.
GET/v1/mail-shop/products
The two mail-shop warehouses + automatic warehouse 99. products[]: warehouse (1 | 2), code (gm_cookie | gm_login), delivers (fields of every account), priceVnd (YOUR price), listPriceVnd (list price), stock, available, maxQty (most one order can take now). auto: order (the order warehouse 99 buys in), priceVnd (cheapest warehouse), available.
Warehouse 1 stock = what the source publishes (refreshed every minute; the source checks accounts are live at purchase time, so you may get fewer — the shortfall is refunded). Warehouse 2 = a reference number from a source sharing the same stock, may be off by a few (null = could not be read — just buy); a shortfall becomes a partial order with the rest refunded. available = false ⇒ do not buy from that warehouse (out of stock / paused). Prices can change — read the catalog again before a large purchase.
Örnek
curl "https://otpgmail.net/v1/mail-shop/products" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "products": [
      {
        "warehouse": 1,
        "code": "gm_cookie",
        "name": "Short-lived live Gmail — with cookies + inbox link",
        "description": "Short-lived personal Gmail account. You get the email · password · login cookies · an inbox link (add ?json to read the emails as JSON).",
        "terms": "• Warranty covers ONLY the first successful sign-in, within 2 hours of purchase.\n• These Gmail accounts typically last 6–24 hours: use them right after purchase.",
        "delivers": [
          "email",
          "password",
          "cookies",
          "inboxUrl",
          "inboxJsonUrl"
        ],
        "priceVnd": 3300,
        "listPriceVnd": 3300,
        "stock": 1840,
        "available": true,
        "maxQty": 500
      },
      {
        "warehouse": 2,
        "code": "gm_login",
        "name": "Short-lived live Gmail — with a quick login link",
        "description": "Short-lived personal Gmail account that has been used on a few services. You get the email · password · a quick login link.",
        "terms": "• Warranty covers ONLY the first successful sign-in, within 2 hours of purchase.\n• Sign in with the link in a DESKTOP BROWSER.",
        "delivers": [
          "email",
          "password",
          "loginUrl"
        ],
        "priceVnd": 6000,
        "listPriceVnd": 6000,
        "stock": 141,
        "available": true,
        "maxQty": 100
      }
    ],
    "auto": {
      "warehouse": 99,
      "priceVnd": 3300,
      "available": true,
      "order": [
        1,
        2
      ]
    }
  }
}
Olası hatalar: UNAUTHORIZED
GET/v1/mail-shop/quote
Call quote to see the total first (nothing is reserved). Warehouse 99 ⇒ route[] = planned split by known stock; available = false ⇒ that quantity cannot be bought right now.
Parametreler
AdTürZorunluAçıklama
warehouse1 | 2 | 99HayırMail-shop warehouse: 1 = email + password + cookies + inbox link · 2 = email + password + login link · 99 = automatic, cheapest first. Send warehouse OR product
productstringHayırInstead of warehouse: gm_cookie (= warehouse 1) | gm_login (= warehouse 2)
quantitynumberHayırNumber of accounts (default 1)
Örnek
curl "https://otpgmail.net/v1/mail-shop/quote?warehouse=99&quantity=10" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "warehouse": 99,
    "quantity": 10,
    "unitPriceVnd": 3300,
    "totalVnd": 38400,
    "available": true,
    "stock": null,
    "maxQty": 500,
    "route": [
      {
        "warehouse": 1,
        "quantity": 8,
        "unitPriceVnd": 3300
      },
      {
        "warehouse": 2,
        "quantity": 2,
        "unitPriceVnd": 6000
      }
    ]
  }
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR, MAILSHOP_PRODUCT_NOT_FOUND
POST/v1/mail-shop/orders
Buy: you are charged at once, then the system buys from the source and delivers. The response is the order — usually already completed with items[]; status = pending ⇒ poll GET /v1/mail-shop/orders/{id} every 5 seconds. The call waits up to about 16 seconds for the delivery.
Idempotency-Key is required (400 without it). Not enough stock ⇒ MAILSHOP_OUT_OF_STOCK (error.details.stock = how many you can buy now, nothing charged); over the per-order limit ⇒ MAILSHOP_QTY_LIMIT (error.details.max). 502 MAILSHOP_SUPPLIER_ERROR = the source refused at once: a failed order was recorded and fully refunded (error.details.orderId) — retry with a new key.
Parametreler
AdTürZorunluAçıklama
warehouse1 | 2 | 99HayırMail-shop warehouse: 1 = email + password + cookies + inbox link · 2 = email + password + login link · 99 = automatic, cheapest first. Send warehouse OR product
productstringHayırInstead of warehouse: gm_cookie (= warehouse 1) | gm_login (= warehouse 2)
quantitynumberHayırNumber of accounts (default 1)
Idempotency-KeystringEvetHeader: a new UUID for every new purchase — reuse it only to retry that same purchase
Örnek
# Idempotency-Key zorunludur: her satın alma için yeni bir UUID — aynı anahtarı yalnızca zaman aşımından sonra yeniden denerken kullanın
# warehouse: 1 = cookies + inbox link · 2 = login link · 99 = cheapest first
curl -X POST "https://otpgmail.net/v1/mail-shop/orders" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  --max-time 60 \
  -d '{"warehouse":99,"quantity":5}'
Örnek yanıt
{
  "success": true,
  "data": {
    "id": "p3x9k2m7q1w8e5r4",
    "requestedWarehouse": 99,
    "warehouse": 1,
    "productCode": "gm_cookie",
    "quantity": 2,
    "deliveredCount": 2,
    "unitPriceVnd": 3300,
    "chargedVnd": 9300,
    "refundVnd": 0,
    "status": "completed",
    "channel": "api",
    "route": [
      {
        "warehouse": 1,
        "quantity": 1,
        "unitPriceVnd": 3300
      },
      {
        "warehouse": 2,
        "quantity": 1,
        "unitPriceVnd": 6000
      }
    ],
    "message": null,
    "createdAt": 1760000400,
    "completedAt": 1760000409,
    "items": [
      {
        "lineNo": 1,
        "warehouse": 1,
        "email": "[email protected]",
        "password": "Pw7Xq!k3d",
        "rawLine": "[email protected]|Pw7Xq!k3d||[{\"domain\":\".google.com\",\"name\":\"SID\",\"value\":\"g.a000…\"}]",
        "cookies": "[{\"domain\":\".google.com\",\"name\":\"SID\",\"value\":\"g.a000…\"}]",
        "inboxUrl": "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d",
        "inboxJsonUrl": "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d?json",
        "twoFaUrl": "https://otpgmail.net/2fa/Q7xK2mP9vL4tR8wN3cB6yH1d",
        "inboxLinkExpiresAt": 1762592400
      },
      {
        "lineNo": 2,
        "warehouse": 2,
        "email": "[email protected]",
        "password": "Qp9!rT2",
        "rawLine": "[email protected]!rT2----no----https://login.example/google/login?uid=s2c38a3b",
        "loginUrl": "https://login.example/google/login?uid=s2c38a3b",
        "otpUrl": "https://otpgmail.net/api/mail-shop/otp/p3x9k2m7q1w8e5r4.2.Zx8Kq2Lm4Np6Rt0Vw3Yb5c",
        "otpService": "vinted"
      }
    ]
  }
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR, MAILSHOP_PRODUCT_NOT_FOUND, MAILSHOP_DISABLED, MAILSHOP_QTY_LIMIT, MAILSHOP_OUT_OF_STOCK, INSUFFICIENT_BALANCE, MAILSHOP_SUPPLIER_ERROR, RATE_LIMITED, DUPLICATE_REQUEST, MAINTENANCE
GET/v1/mail-shop/orders
Your mail-shop orders, newest first (page / pageSize, up to 100 per page) — without items[]: fetch an order to get its accounts. Orders bought on the web are listed too (channel = web).
Parametreler
AdTürZorunluAçıklama
pagenumberHayırPage (default 1)
pageSizenumberHayırOrders per page (default 20, max 100)
Örnek
curl "https://otpgmail.net/v1/mail-shop/orders?page=1&pageSize=20" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "items": [
      {
        "id": "p3x9k2m7q1w8e5r4",
        "requestedWarehouse": 99,
        "warehouse": 1,
        "productCode": "gm_cookie",
        "quantity": 2,
        "deliveredCount": 2,
        "unitPriceVnd": 3300,
        "chargedVnd": 9300,
        "refundVnd": 0,
        "status": "completed",
        "channel": "api",
        "route": [
          {
            "warehouse": 1,
            "quantity": 1,
            "unitPriceVnd": 3300
          },
          {
            "warehouse": 2,
            "quantity": 1,
            "unitPriceVnd": 6000
          }
        ],
        "message": null,
        "createdAt": 1760000400,
        "completedAt": 1760000409
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 20
  }
}
Olası hatalar: UNAUTHORIZED
GET/v1/mail-shop/orders/{id}
One order with every account delivered so far (an order still delivering already shows what has arrived). route[] = which warehouse, how many, at what price.
Poll every 5 seconds while status = pending; completed / partial / failed / refunded are final. An order of many warehouse-1 accounts (cookies) can weigh several MB — stop polling once it is final.
Parametreler
AdTürZorunluAçıklama
idstringEvetOrder ID (data.id returned by the purchase)
Örnek
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "id": "p3x9k2m7q1w8e5r4",
    "requestedWarehouse": 99,
    "warehouse": 1,
    "productCode": "gm_cookie",
    "quantity": 2,
    "deliveredCount": 2,
    "unitPriceVnd": 3300,
    "chargedVnd": 9300,
    "refundVnd": 0,
    "status": "completed",
    "channel": "api",
    "route": [
      {
        "warehouse": 1,
        "quantity": 1,
        "unitPriceVnd": 3300
      },
      {
        "warehouse": 2,
        "quantity": 1,
        "unitPriceVnd": 6000
      }
    ],
    "message": null,
    "createdAt": 1760000400,
    "completedAt": 1760000409,
    "items": [
      {
        "lineNo": 1,
        "warehouse": 1,
        "email": "[email protected]",
        "password": "Pw7Xq!k3d",
        "rawLine": "[email protected]|Pw7Xq!k3d||[{\"domain\":\".google.com\",\"name\":\"SID\",\"value\":\"g.a000…\"}]",
        "cookies": "[{\"domain\":\".google.com\",\"name\":\"SID\",\"value\":\"g.a000…\"}]",
        "inboxUrl": "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d",
        "inboxJsonUrl": "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d?json",
        "twoFaUrl": "https://otpgmail.net/2fa/Q7xK2mP9vL4tR8wN3cB6yH1d",
        "inboxLinkExpiresAt": 1762592400
      },
      {
        "lineNo": 2,
        "warehouse": 2,
        "email": "[email protected]",
        "password": "Qp9!rT2",
        "rawLine": "[email protected]!rT2----no----https://login.example/google/login?uid=s2c38a3b",
        "loginUrl": "https://login.example/google/login?uid=s2c38a3b",
        "otpUrl": "https://otpgmail.net/api/mail-shop/otp/p3x9k2m7q1w8e5r4.2.Zx8Kq2Lm4Np6Rt0Vw3Yb5c",
        "otpService": "vinted"
      }
    ]
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND
GET/v1/mail-shop/orders/{id}/download
The delivered accounts as .txt (text/plain), separated by |. The FIRST LINE is the column header: warehouse 1 email|password|cookies|inboxUrl · warehouse 2 email|password|loginUrl · a 99 order with both warehouses ⇒ email|password|cookies|inboxUrl|loginUrl (missing cells empty).
cookies is one-line JSON and may contain | — split email and password at the first two |, the link at the last | (with extra columns ⇒ the links after cookies at the last | separators — links never contain |; read the header line for their order). Nothing delivered yet ⇒ 409 VALIDATION_ERROR. Add <c>?otp=1</c> ⇒ warehouse 2 gets a LAST column <c>otpUrl</c> (the Vinted OTP link — empty when the account has none): email|password|loginUrl|otpUrl. Without it ⇒ exactly the columns above. Add <c>?twofa=1</c> ⇒ warehouse 1 gets a LAST column <c>twoFaUrl</c> (the 2FA link — same code as inboxUrl; GET ⇒ just the 6 digits; empty when the link is off / expired): email|password|cookies|inboxUrl|twoFaUrl. Combines with <c>otp=1</c> — fixed column order: …|loginUrl|otpUrl|twoFaUrl (a 99 order with both warehouses). Without it ⇒ the default layout above.
Parametreler
AdTürZorunluAçıklama
idstringEvetOrder ID (data.id returned by the purchase)
Örnek
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID/download" \
  -H "Authorization: Bearer og_xxx..." \
  -o mail-ORDER_ID.txt
Örnek yanıt
email|password|cookies|inboxUrl
[email protected]|Pw7Xq!k3d|[{"domain":".google.com","name":"SID","value":"g.a000…"}]|https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d
Olası hatalar: UNAUTHORIZED, NOT_FOUND, VALIDATION_ERROR
GET/v1/mail-shop/orders/{id}/items/{lineNo}/inbox
Latest emails of a WAREHOUSE-1 account (sender, subject, time, extracted code / link, sanitized full email). Without an API key: GET the account's inboxJsonUrl (same emails, JSON).
max = 10 (default) | 20 | 50 | 100 | 200 — more emails take longer (up to about a minute). Cached for 15 seconds; every real read counts toward the hourly limit. 409 VALIDATION_ERROR = a warehouse-2 account (no inbox reading); 409 PROVIDER_ERROR with details.dead = the account was locked or removed.
Parametreler
AdTürZorunluAçıklama
idstringEvetOrder ID (data.id returned by the purchase)
lineNonumberEvetAccount number within the order (items[].lineNo)
maxnumberHayırNumber of latest emails: 10 (default), 20, 50, 100 or 200
Örnek
# Warehouse 1 accounts only; max = 10 | 20 | 50 | 100 | 200
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID/items/1/inbox?max=20" \
  -H "Authorization: Bearer og_xxx..." \
  --max-time 70

# Same emails without an API key: GET the account's inboxJsonUrl
curl "https://otpgmail.net/mail/Q7xK2mP9vL4tR8wN3cB6yH1d?json&max=20"
Örnek yanıt
{
  "success": true,
  "data": {
    "email": "[email protected]",
    "letters": [
      {
        "key": "h:9f2c4e1a7b3d5c80",
        "from": "Instagram [email protected]",
        "subject": "350038 is your Instagram code",
        "receivedAt": 1760000520,
        "code": "350038",
        "content": "<html><body><p>Enter this confirmation code in the app: 350038</p></body></html>"
      }
    ],
    "max": 10,
    "total": 8,
    "fetchedAt": 1760000530,
    "cached": false
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, VALIDATION_ERROR, RATE_LIMITED, PROVIDER_ERROR
GET/v1/mail-shop/orders/{id}/items/{lineNo}/status
Is a bought warehouse-1 account still alive: live = true / false, or null when it cannot be determined. Counts toward the hourly inbox-read limit.
Parametreler
AdTürZorunluAçıklama
idstringEvetOrder ID (data.id returned by the purchase)
lineNonumberEvetAccount number within the order (items[].lineNo)
Örnek
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID/items/1/status" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "email": "[email protected]",
    "live": true,
    "reason": null,
    "checkedAt": 1760000600
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, VALIDATION_ERROR, RATE_LIMITED, PROVIDER_ERROR
GET/v1/mail-shop/orders/{id}/items/{lineNo}/2fa
The current 2FA code (6-digit TOTP, changes every 30 seconds) of a warehouse-1 account — some warehouse-1 accounts have 2-step verification on (Google asks for a code at a password sign-in). none = true ⇒ the account has no 2FA (code / expiresIn null). expiresIn = seconds the code stays valid — ask again after that. Without an API key: GET the account's twoFaUrl (the body is just the 6 digits).
The server caches the code until it expires (every call within those 30 seconds gets the same code) — it does NOT count toward the hourly inbox-read limit. Calling too fast ⇒ 429 (retryAfterSec); a warehouse-2 account ⇒ 409; a locked account ⇒ 409 (details.dead).
Parametreler
AdTürZorunluAçıklama
idstringEvetOrder ID (data.id returned by the purchase)
lineNonumberEvetAccount number within the order (items[].lineNo)
Örnek
curl "https://otpgmail.net/v1/mail-shop/orders/ORDER_ID/items/1/2fa" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "none": false,
    "code": "424819",
    "expiresIn": 24
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, VALIDATION_ERROR, RATE_LIMITED, PROVIDER_ERROR

Sipariş yaşam döngüsü

DurumAçıklama
Kod bekleniyorYeni oluşturulmuş sipariş, ilk kodu bekliyor. GET /v1/orders/{id} adresini her 3–5 saniyede bir sorgulayın.
Tamamlandıİlk kod geldi — durum hemen değişir. Hizmet birden fazla kod gönderiyorsa daha fazla kod gelmeye devam edebilir (sipariş süresi içinde ek ücret yok; sınır ve pencere kaynağa göre); sorgulamaya devam edin, her yeni kod otp[] dizisinin sonunda görünür.
İptal edildi%100 iade edilir. Şu durumlarda olur: /cancel çağırırsınız (henüz kod yokken) ya da codeDeadlineAt zamanına kadar (en fazla 25 dakika) kod gelmez.
Önemli notlar:
  • Sipariş waiting_code durumundayken kodu hemen yakalamak için GET /v1/orders/{id} adresini her 3–5 saniyede bir sorgulayın.
  • İlk kod gelir gelmez durum hemen completed olur.
  • codeDeadlineAt zamanına kadar kod gelmezse (en fazla 25 dakika; kaynak 2: 20 dakika; kaynak 4'ün bazı tedarikçilerinde daha kısa) ⇒ sistem siparişi iptal eder ve %100 iade eder (status = cancelled).
  • otp[] dizisi en eski ilk, en yeni son sıralıdır. Son kodu otp[otp.length - 1] ile okuyun (Python: otp[-1]).
  • completed bir sipariş kod almaya otomatik olarak devam eder: GET /v1/orders/{id} adresini sorgulamaya devam edin, her yeni kod otp[] dizisinin sonunda görünür. Hizmet birden fazla kod gönderiyorsa ek kodlar sipariş süresi içinde ücretsizdir; sınır ve süre kiralamadan önce gösterilir (offers[] içindeki maxCodes ve fee; kaynak 1'de gelen kutusu genellikle son koddan sonra yaklaşık 25 dakika açık kalır). Açıkça başka bir kod istemek için (ör. kayıttan sonra giriş yaparken): POST /v1/orders/{id}/next-code — her kaynakta çalışır ve yalnızca ücretsiz penceresi dışındaki kaynak 2 ücret alır.
  • Hizmet gelen kutusu başına yalnızca bir koda izin veriyorsa otp[] o kodda durur. Yanıtlar normal kalır, hata olmaz — sorgulamayı ne zaman bırakacağınıza siz karar verirsiniz.
  • otp[].code genellikle kısa bir koddur (rakam / harf) ya da bir bağlantıdır. Kodu ayıklanamayan bir e-posta (hoş geldin e-postaları, bültenler, alışılmadık kod biçimleri…) otp[].code içinde olduğu gibi (HTML veya metin) teslim edilir — 80 karakterden uzunsa, satır sonu içeriyorsa ya da HTML ise tam e-posta sayın ve kodu ya da bağlantıyı içinde kendiniz arayın.
  • POST /v1/orders, sağlayıcının bir gelen kutusu atamasını bekler; bu yüzden genellikle ~0,3 saniye sürer ancak yoğun saatlerde (nadiren) 10 saniyeye kadar çıkabilir. 5 saniye sonra vazgeçip erken yeniden denemek yerine istemci zaman aşımını ≈ 15 saniyeye ayarlayın — yeniden denediğinizde de aynı Idempotency-Key değerini kullanın.
  • Kod almış bir sipariş iptal edilemez ve iade edilemez — iptal çağrısı ORDER_NOT_CANCELLABLE döndürür.
  • Bir @icloud.com gelen kutusu kiralamak için sipariş oluştururken "domain": "icloud.com" gönderin (Gmail için belirtmeyin; mevcut botlarda değişiklik gerekmez). Hizmet iCloud'u desteklemiyorsa veya iCloud geçici olarak devre dışıysa DOMAIN_UNAVAILABLE alırsınız — Gmail'e geçin, kiralama hemen gerçekleşir. Yaşam döngüsü, iptal ve iade kuralları ile kodları okuma biçimi Gmail ile tamamen aynıdır.
  • Kendi stokundan hizmetler (provider = "inventory", örn. Cointiply — bkz. GET /v1/services) yalnızca iCloud'dur; her e-posta otp[].code içinde bir bağlantı olarak, kind, label ve text içindeki tam e-posta metniyle birlikte gelir. Bir sipariş, rules.windowMinutes dakika içinde (windowEndsAt anına kadar) en fazla rules.maxCodes e-posta alır, iptal edilemez (ORDER_NOT_CANCELLABLE) ve e-posta gelmeden süre dolarsa iade yapılmadan cancelled olur. Aynı gelen kutusunda almaya devam etmek için canRerent true iken POST /v1/orders/{id}/rerent çağrısı yapın (fiyat: rerentPriceVnd). Diğer tüm hizmetlerde / siparişlerde provider = "standard" olur — 2026-10-24 itibarıyla provider yalnızca iki değer alır: "standard" | "inventory" (gerçek depo warehouse alanındadır); yalnızca "inventory" ile karşılaştırın.
  • Kaynak 2 siparişleri (warehouse = 2): kodlar fee.freeHours saat boyunca ücretsizdir; ücretsiz pencere kapandığında yeni kodlar gelmez — bir pencere daha açmak için confirmFee = true ile POST /v1/orders/{id}/next-code çağrısı yapın (nextCodeFee.feePriceVnd ödenir), nextCodeFee.hardUntil sınırına kadar. Normal hizmetlerin Kaynak 3 siparişleri: 24 saat ücretsiz kod, kod gelmeden önce iptal edilebilir, sonrasında rerent kullanın. Kaynak 4 siparişleri: yeni kodlar siparişi okuduğunuzda otp[] dizisine düşer, rentExpiresAt zamanına kadar ücretsizdir; tek kod veren kaynakta ilk koddan sonra nextCodeBlockReason = "max_codes" olur.
  • Aynı anda çok sayıda sipariş mi var? POST /v1/orders/status ile çağrı başına en fazla 100 tanesini sorgulayın — Çok sayıda siparişin durumu bölümüne bakın.

İstek sınırları

Sınırlar her API anahtarı için geçerlidir (bir hesabın kendine özel sınırları olabilir; yoksa sitenin varsayılan sınırları uygulanır):
  • saniyede 100 istek — birkaç saniyelik kısa yoğunluklar
  • dakikada 3000 istek — dakika başına toplam trafik
Bir sınırın aşılması, Retry-After: <seconds> başlığı ve {"success":false,"error":{"code":"RATE_LIMITED",...}} gövdesiyle birlikte HTTP 429 döndürür. Yeniden denemeden önce başlıkta verilen saniye kadar bekleyin. Hata gövdesi aynı saniye sayısını error.retryAfterSec içinde de taşır (error.retryable = true ile birlikte).

Hata kodları

Her hatanın biçimi aynıdır: {"success":false,"error":{"code":"...","message":"...","retryable":false,"retryAfterSec":null}}
2026-10-17 tarihinden itibaren her /v1 hatasında ayrıca error.retryable ve error.retryAfterSec bulunur (eklenen alanlar — mevcut istemcilerin değişmesi gerekmez; details aynı kalır). retryable = true ⇒ aynı çağrı daha sonra başarılı olabilir: retryAfterSec saniye (≥ 1 tam sayı) bekleyip yeniden gönderin — stok yok / gelen kutusu yok / kaynak duraklatıldı / sağlayıcı hatası ⇒ 5 sn; 429 RATE_LIMITED ⇒ Retry-After başlığı; aynı Idempotency-Key ile ilk istek hâlâ sürerken 409 DUPLICATE_REQUEST ⇒ 2 sn. retryable = false (retryAfterSec = null) ⇒ nedeni düzeltmedikçe (bakiye, bekleyen sipariş sınırı, parametreler, API anahtarı…) yeniden çağırmak işe yaramaz. POST /v1/orders yanıtındaki partial.reason da aynı kuralları izler. Stok yok anlamındaki 409 yanıtında (OUT_OF_STOCK, WAREHOUSE_UNAVAILABLE, ALL_WAREHOUSES_EXHAUSTED) yeniden denemeden önce retryAfterSec saniyenin tamamını bekleyin — daha erken denemek genellikle aynı yanıtı döndürür — ve yeniden kiralamadan önce GET /v1/services içindeki stock / offers[].stock değerine bakın; zaten kiraladığınız siparişleri sık sık sorgulamak yerine webhook ile izleyin.
Örnek hata yanıtları
HTTP/1.1 409 Conflict
{
  "success": false,
  "error": {
    "code": "OUT_OF_STOCK",
    "message": "This service is currently out of stock",
    "retryable": true,
    "retryAfterSec": 5
  }
}

HTTP/1.1 429 Too Many Requests
Retry-After: 1
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded, retry after 1s",
    "retryable": true,
    "retryAfterSec": 1
  }
}

HTTP/1.1 402 Payment Required
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient balance to rent an inbox",
    "retryable": false,
    "retryAfterSec": null
  }
}
Hata koduHTTPretryable · retryAfterSecAnlamı
UNAUTHORIZED401false · nullAPI anahtarı geçersiz veya eksik.
ACCOUNT_LOCKED403false · nullHesap kilitli — anahtarıyla yapılan her istek reddedilir. Destekle iletişime geçin.
FORBIDDEN403false · nullKiralama işlenirken hesap artık etkin değildi (az önce kilitlendi).
NOT_FOUND404false · nullHesabınızda bu kimliğe sahip sipariş / toplu kiralama / gelen kutusu yok (başka bir hesabın siparişleri de 404 döndürür).
VALIDATION_ERROR400false · nullİstek parametreleri geçersiz (yanlış tür, eksik zorunlu alan vb.).
INSUFFICIENT_BALANCE402false · nullHesap bakiyesi siparişi ödemek için yetersiz.
SERVICE_DISABLED409false · nullHizmet kodu yok ya da hizmet geçici olarak kapalı. Doğru kodu GET /v1/services yanıtından alın.
OUT_OF_STOCK409true · 5İstek anında hizmette (seçilen gelen kutusu türü için) uygun gelen kutusu yok.
DOMAIN_UNAVAILABLE409false · nullHizmet seçilen gelen kutusu türünü sunmuyor — iCloud henüz desteklenmiyor / geçici olarak devre dışı veya hizmette gmx.com gelen kutusu yok. Gmail kiralamak için domain "gmail.com" gönderin (veya alanı belirtmeyin).
WAREHOUSE_UNAVAILABLE409true · 5 / falseSeçilen kaynak bu hizmeti/gelen kutusu türünü satmıyor, duraklatılmış veya az önce tükendi. offers[] içinden başka bir kaynak seçin ya da stokta olan birini sistemin seçmesi için warehouse = 99 gönderin. Bu kaynak (veya bu hizmeti satan tüm kaynaklar) hesabınız için kullanılamıyorsa retryable = false olur — tekrar çağırmak işe yaramaz, başka bir kaynak kullanın.
ALL_WAREHOUSES_EXHAUSTED409true · 5Yalnızca warehouse = 99 ile: stokta olan her kaynak (en ucuzdan başlayarak) denendi ve hepsinin stoğu tükenmiş veya hata veriyor — ya da her kaynak sıfır stok bildiriyor. Ücret alınmadı; daha sonra tekrar deneyin.
NO_MAILS_AVAILABLE503true · 5Sağlayıcının bu hizmet için gelen kutusu kalmadı (geçici olarak tükendi).
QUANTITY_EXCEEDED400false · nullquantity, istek başına en yüksek değeri aşıyor (şu anda 200).
WAITING_LIMIT_REACHED429false · nullAynı anda kod bekleyen çok fazla sipariş var (hesabınızın eşzamanlı waiting_code sipariş sınırı aşıldı) — bazılarının bitmesini bekleyip yeniden kiralayın.
ORDER_NOT_CANCELLABLE409false · nullSipariş iptal edilemez — zaten bir kodu olabilir veya artık waiting_code durumunda değildir. next-code da sipariş henüz ilk kodunu almamışken bu kodu döndürür.
RERENT_NOT_AVAILABLE409false · nullSipariş yeniden kiralanamaz. Kaynak 3: gelen kutusunun en son siparişi değil, gelen kutusu artık hesabınıza atanmış değil veya önceki alma penceresi halen açık. Kaynak 2: sipariş henüz kapanmadı (hâlâ kod alabilir — next-code kullanın), yeniden kiralamak için çok eski, e-postada başka etkin sipariş var veya hizmet duraklatıldı. Kaynak 1 ve 4'te yeniden kiralama yok.
RERENT_EMAIL_BANNED409false · nullKaynak 2 yeniden kiralama: sağlayıcı e-postanın hizmet tarafından kilitlendiğini bildiriyor (email banned) — yeniden kiralanamaz; ücret alınmaz.
RERENT_MAIL_GONE409false · nullKaynak 2 yeniden kiralama: sağlayıcı bu e-postayı artık yeniden açamıyor — yeni bir tane kiralayın; ücret alınmaz.
NEXT_CODE_FEE_CONFIRM409false · nullKaynak 2 siparişinin ücretsiz penceresi bitti — ücreti (nextCodeFee.feePriceVnd) ödemek için next-code'u confirmFee: true ile tekrar çağırın. Henüz ücret alınmadı.
EMAIL_BANNED409false · nullE-posta hizmet tarafından kilitlendi (sağlayıcı email banned bildiriyor) — daha fazla kod alamaz; yenisini kiralayın. 2026-10-02'den itibaren (önceden ORDER_EXPIRED, aynı HTTP 409).
ORDER_EXPIRED409false · nullSipariş artık kod alamaz — süresi doldu (rentExpiresAt / nextCodeFee.hardUntil), sağlayıcı gelen kutusunu kapattı, kod sınırına (maxCodes) ulaşıldı ya da hizmette "sonraki kod" yok. Neden order.nextCodeBlockReason içinde.
RATE_LIMITED429true · = Retry-AfterAPI anahtarınız için saniyede 100 veya dakikada 3000 istekten fazla (hesapların kendine özel sınırları olabilir). Retry-After başlığı kaç saniye bekleyeceğinizi söyler. Kaynak 2'de POST /v1/orders ve /rerent, hesap son 60 dakikada kod almamış çok sayıda kaynak 2 siparişini iptal ettiğinde ve kaynak 2 siparişlerinin çok azı kod aldığında da bu kodu döndürür — iptal oranı düşene kadar kaynak 2'den kiralama duraklar ("warehouse": 99 da bu hatayla kaynak 2'de durur — bu sürede başka bir kaynak seçin). Facebook / Instagram (fb, fbb, ig) muaftır.
DUPLICATE_REQUEST409true · 2 / falseIdempotency-Key farklı bir içerik veya uç noktayla zaten kullanıldı ya da bu anahtarla yapılan ilk istek hâlâ sürüyor (biraz sonra yeniden deneyin). Başka bir sipariş oluşturmak için yeni bir anahtar üretin.
PROVIDER_ERROR502true · 5Gelen kutusu sağlayıcısından hata (geçici — birkaç saniye sonra yeniden deneyin).
MAINTENANCE503false · nullSistem bakımda — sipariş oluşturma ve iptal etme duraklatıldı.
MAILSHOP_DISABLED503false · nullKısa ömürlü Gmail satın alma duraklatıldı veya bu ürün kapalı — daha sonra tekrar deneyin.
MAILSHOP_PRODUCT_NOT_FOUND404false · nullBu koda sahip ürün yok — doğru kodu şuradan alın: GET /v1/mail-shop/products.
MAILSHOP_OUT_OF_STOCK409false · nullBu adet için mevcut fiyattan yeterli stok yok — error.details.stock = şu anda satın alabileceğiniz hesap sayısı.
MAILSHOP_QTY_LIMIT400false · nullquantity, sipariş başına en yüksek değeri aşıyor (şu anda 500) — error.details.max.
MAILSHOP_SUPPLIER_ERROR502false · nullTedarikçi satın almayı hemen reddetti: failed durumunda bir sipariş kaydedildi ve tutar iade edildi (error.details.orderId). Daha sonra yeni bir Idempotency-Key ile tekrar deneyin.
INTERNAL500false · nullBeklenmeyen sunucu hatası — daha sonra tekrar deneyin; sürerse destekle iletişime geçin.

Webhook'lar (anlık bildirim)

Hesap başına bir URL kaydedin; bir sipariş yeni kod aldığında (order.code) ya da iptal edildiğinde / iade edildiğinde (order.cancelled) bu URL'ye imzalı bir JSON olayı POST ederiz. Webhook'lar isteğe bağlıdır ve hesabınızın tüm siparişlerini kapsar (web ve API). Gönderim en iyi çaba esaslıdır — yedek olarak seyrek sorgulamaya devam edin (aşağıya bakın).
3 adımda kurulum
  1. URL'nizle (isteğe bağlı olarak events ile) PUT /v1/webhook çağırın — data.secret değerini (64 onaltılık karakter) saklayın: her gönderimi doğrulamak için gerekir. PUT'u tekrar çağırmak aynı secret'ı korur.
  2. POST /v1/webhook/test — hemen bir ping olayı göndeririz ve sunucunuzun ne yanıt verdiğini döndürürüz (ok, httpStatus, error).
  3. Uç noktanız 5 saniye içinde herhangi bir 2xx ile yanıt vermelidir — önce yanıtlayın, olayı sonra işleyin. Diğer her şey (3xx, 4xx, 5xx, zaman aşımı, bağlantı hatası) başarısız sayılır ve yeniden denenir.
URL http:// veya https:// ile başlamalı (geçerli sertifika) ve internetten erişilebilir olmalıdır: localhost, özel, link-local, multicast ve ayrılmış adresler (10.x, 172.16–31.x, 192.168.x, 169.254.x, fc00::/7, fe80::/10…) ile OTPGmail'in kendi sunucuları VALIDATION_ERROR ile reddedilir. Alan adı her gönderimden önce yeniden çözümlenir. Yönlendirmeler izlenmez — son URL'yi kaydedin.
İstek biçimi
Her gönderim, URL'nize JSON gövdeli (UTF-8) bir HTTP POST isteğidir ve şu başlıkları taşır:
BaşlıkDeğer
Content-Typeapplication/json
User-AgentOTPGmail-Webhook/1
X-OTPGmail-EventOlay adı: order.code, order.cancelled veya ping
X-OTPGmail-DeliveryOlayın benzersiz kimliği (UUID) — gövdedeki deliveryId ile aynıdır ve her yeniden denemede değişmez
X-OTPGmail-TimestampBu denemenin imzalandığı Unix zamanı (saniye) — gövdedeki sentAt ile aynıdır
X-OTPGmail-Signaturesha256= + timestamp + "." + ham gövde üzerinde secret'ınızla hesaplanan HMAC-SHA256'nın küçük harfli hex değeri
İmzayı doğrulayın
Anahtar olarak secret'ınızı kullanıp X-OTPGmail-Timestamp + . + ham istek gövdesi üzerinde HMAC-SHA256'yı küçük harfli hex olarak hesaplayın ve sha256= sonrasındaki değerle sabit zamanlı karşılaştırın. Anahtar, 64 karakterlik secret dizesinin kendisidir (UTF-8 baytları — hex olarak çözmeyin). Ham baytları kullanın: JSON'u ayrıştırıp yeniden serileştirmek baytları değiştirir. Saatinizden 5 dakikadan fazla sapan zaman damgalarını reddedin (tekrar oynatma koruması).
Alıcı örnekleri (Python ve Node yalnızca standart kütüphaneyi kullanır; curl komutu kendi alıcınıza doğru imzalı bir deneme gönderimi yapar)
# Yerel test: alıcınıza bizimkiyle birebir aynı şekilde imzalanmış bir gönderim yollayın
SECRET="9f2c6d1e8b7a4f3c5e0d2b1a6c9e8f7d3b5a1c2e4f6a8b0d9c7e5f3a1b2c4d6e"
TS=$(date +%s)
BODY='{"event":"ping","deliveryId":"6f1d2c3b-8a9e-4f70-b1c2-d3e4f5a6b7c8","sentAt":'$TS'}'
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')
curl -X POST "http://localhost:8080/" \
  -H "Content-Type: application/json" \
  -H "X-OTPGmail-Event: ping" \
  -H "X-OTPGmail-Delivery: 6f1d2c3b-8a9e-4f70-b1c2-d3e4f5a6b7c8" \
  -H "X-OTPGmail-Timestamp: $TS" \
  -H "X-OTPGmail-Signature: sha256=$SIG" \
  -d "$BODY"
Olaylar
OlayNe zaman gönderilir
order.codeBir sipariş yeni kod aldı — her kod için bir olay, aynı posta kutusundaki sonraki kodlar dahil. code yeni koddur; otp siparişin o ana kadarki tüm kodlarını eskiden yeniye listeler (GET /v1/orders/{id} ile aynı; gövde 64 KB'yi aşacaksa yalnızca yeni kod).
order.cancelledBir sipariş iptal edildi veya iade edildi — sipariş başına bir kez: süre dolmadan kod gelmedi (timeout), siz iptal ettiniz (user), bir yönetici iptal etti (admin) ya da depo arızası nedeniyle iade edildi (provider). refundVnd = bakiyenize iade edilen VND (hizmet kuralları iade öngörmüyorsa 0).
pingYalnızca POST /v1/webhook/test ile gönderilir.
Olay alanları
AlanTürAçıklama
eventstringOlay adı (X-OTPGmail-Event başlığında da bulunur)
deliveryIdstringOlayın benzersiz kimliği (UUID, = X-OTPGmail-Delivery) — tekrarları atlamak için saklayın
sentAtnumberBu denemenin Unix zamanı (= X-OTPGmail-Timestamp)
orderIdstringSipariş kimliği — GET /v1/orders/{id} ile aynı
servicestringHizmet kodu
warehouse1 | 2 | 3 | 4 | nullPosta kutusunu sağlayan depo 1–4; sipariş hiç posta kutusu almadıysa null
domainstringPosta kutusu alanı: gmail.com, icloud.com veya gmx.com
emailstring | nullKiralanan posta kutusu adresi
codestringYalnızca order.code: yeni kod — otp[].code gibi bir bağlantı ya da e-postanın tamamı da olabilir
receivedAtnumberYalnızca order.code: kodun geldiği Unix zamanı
statusstringO andaki sipariş durumu: order.code için completed, order.cancelled için cancelled (zaten kodu olan bir siparişi yönetici iade ederse completed kalır)
otparrayYalnızca order.code: o ana kadarki tüm kodlar, [{code, receivedAt}], eskiden yeniye
reasonstringYalnızca order.cancelled: timeout | user | admin | provider
refundVndnumberYalnızca order.cancelled: bakiyenize iade edilen VND (0 = iade yok)
Örnek gövde — order.code
{
  "event": "order.code",
  "deliveryId": "6f1d2c3b-8a9e-4f70-b1c2-d3e4f5a6b7c8",
  "sentAt": 1760700125,
  "orderId": "k3m9x2p7q1w8e5r4",
  "service": "fb",
  "warehouse": 1,
  "domain": "gmail.com",
  "email": "[email protected]",
  "code": "482913",
  "receivedAt": 1760700124,
  "status": "completed",
  "otp": [
    {
      "code": "482913",
      "receivedAt": 1760700124
    }
  ]
}
Örnek gövde — order.cancelled
{
  "event": "order.cancelled",
  "deliveryId": "0b7e4c2a-5d1f-4e8b-9a3c-2f6d8e1b4a7c",
  "sentAt": 1760701630,
  "orderId": "p8v2n5c1x7z3m9k4",
  "service": "ig",
  "warehouse": 2,
  "domain": "gmail.com",
  "email": "[email protected]",
  "reason": "timeout",
  "refundVnd": 1500,
  "status": "cancelled"
}
Örnek gövde — ping
{
  "event": "ping",
  "deliveryId": "3c9a1e7f-2b4d-4c6e-8f0a-5d7b9c1e3a2f",
  "sentAt": 1760700000
}
Yeniden deneme, duraklatma ve geçmiş
  • Başarısız bir gönderim 10 sn, 1 dk, 5 dk, 30 dk ve 2 saat sonra yeniden denenir (5 deneme); son deneme de başarısız olursa olay bırakılır (failed).
  • Arka arkaya 50 başarısız deneme (tüm olaylar genelinde) webhook'u duraklatır: GET /v1/webhook pausedAt gösterir, hiçbir şey gönderilmez ve yeni olaylar kuyruğa alınmaz.
  • Devam ettirmek için: PUT /v1/webhook çağrısını tekrarlayın (aynı URL olabilir) veya başarılı bir POST /v1/webhook/test alın — kuyrukta bekleyen olaylar ardından gönderilir.
  • GET /v1/webhook/deliveries son 100 gönderimi durumu, deneme sayısı ve son hatasıyla listeler; geçmiş 7 gün saklanır.
Tekrarlar ve sıralama
Aynı olay birden fazla kez gelebilir (örneğin 2xx yanıtınız kaybolduğunda) ve olaylar sırasız gelebilir (birkaçı paralel gönderilir). İşlenmiş deliveryId değerlerini saklayın ve tekrarları atlayın; bir sipariş için varış sırasına değil en yeni verisine (otp, status) güvenin.
Yedek olarak sorgulamaya devam edin
Webhook'lar gecikebilir (yeniden denemeler) veya kaçırılabilir (webhook duraklatıldı, sunucunuz kapalı). Seyrek bir sorgulama sürdürün — örneğin hâlâ waiting_code olan siparişler için 30–60 sn'de bir GET /v1/orders/{id} — ve API'den gelen sipariş nesnesini doğru kaynak kabul edin.
PUT/v1/webhook
Hesabınızın webhook'unu kaydeder veya günceller. İlk çağrı oluşturur ve yeni bir secret döndürür; sonraki çağrılar secret'ı korur, webhook'u yeniden açar ve duraklatılmışsa devam ettirir. events gönderilmezse: yeni webhook için her iki olay, mevcut webhook için değişmez. URL herkese açık bir adres olmalıdır — aksi halde 400 VALIDATION_ERROR (nedeni error.details.problem içinde).
Parametreler
AdTürZorunluAçıklama
urlstringEvetUç noktanız (http:// veya https://, herkese açık adres, en fazla 2048 karakter)
eventsstring[]HayırGönderilecek olaylar: ["order.code", "order.cancelled"] (varsayılan ikisi de)
Örnek
# data.secret değerini saklayın — her gönderimi doğrulamak için gerekir
curl -X PUT "https://otpgmail.net/v1/webhook" \
  -H "Authorization: Bearer og_xxx..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-server.example/otpgmail-webhook","events":["order.code","order.cancelled"]}'
Örnek yanıt
{
  "success": true,
  "data": {
    "url": "https://your-server.example/otpgmail-webhook",
    "events": [
      "order.code",
      "order.cancelled"
    ],
    "enabled": true,
    "secret": "9f2c6d1e8b7a4f3c5e0d2b1a6c9e8f7d3b5a1c2e4f6a8b0d9c7e5f3a1b2c4d6e",
    "pausedAt": null,
    "consecutiveFailures": 0,
    "createdAt": 1760699000,
    "updatedAt": 1760699000
  }
}
Olası hatalar: UNAUTHORIZED, VALIDATION_ERROR
GET/v1/webhook
Hesabınızın webhook'u; secret, pausedAt ve consecutiveFailures dahil. Kayıtlı webhook yoksa data null olur.
Örnek
curl "https://otpgmail.net/v1/webhook" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "url": "https://your-server.example/otpgmail-webhook",
    "events": [
      "order.code",
      "order.cancelled"
    ],
    "enabled": true,
    "secret": "9f2c6d1e8b7a4f3c5e0d2b1a6c9e8f7d3b5a1c2e4f6a8b0d9c7e5f3a1b2c4d6e",
    "pausedAt": 1760705400,
    "consecutiveFailures": 50,
    "createdAt": 1760699000,
    "updatedAt": 1760705400
  }
}
Olası hatalar: UNAUTHORIZED
DELETE/v1/webhook
Webhook'u kaldırır; kuyrukta bekleyen olaylar bırakılır. Her zaman 200 — kaldırılacak bir şey yoksa data.deleted false olur.
Örnek
curl -X DELETE "https://otpgmail.net/v1/webhook" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "deleted": true
  }
}
Olası hatalar: UNAUTHORIZED
POST/v1/webhook/test
URL'nize hemen bir ping olayı gönderir ve sonucu bildirir: ok (sunucunuz 2xx yanıt verdi), httpStatus, durationMs, error. Başarılı bir test duraklatılmış webhook'u devam ettirir. Dakikada en fazla 10 test; webhook'lar sistem genelinde kapalıyken 503 MAINTENANCE.
Örnek
curl -X POST "https://otpgmail.net/v1/webhook/test" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": {
    "ok": true,
    "httpStatus": 200,
    "durationMs": 143,
    "error": null,
    "deliveryId": "3c9a1e7f-2b4d-4c6e-8f0a-5d7b9c1e3a2f"
  }
}
Sunucunuz 2xx yanıt vermediğinde 200 yanıtı
{
  "success": true,
  "data": {
    "ok": false,
    "httpStatus": 500,
    "durationMs": 88,
    "error": "HTTP 500",
    "deliveryId": "7d2b9f4e-1c6a-4e3b-8d5f-0a9c2e7b1f4d"
  }
}
Olası hatalar: UNAUTHORIZED, NOT_FOUND, RATE_LIMITED, MAINTENANCE
GET/v1/webhook/deliveries
En yeni gönderimler, en yenisi önce (7 gün saklanır): status = queued (sonraki deneme nextAt anında) | delivered | failed | paused; attempts, lastHttpStatus ve lastError ile birlikte. Olay gövdeleri döndürülmez.
Parametreler
AdTürZorunluAçıklama
limitnumberHayırGönderim sayısı, 1–100 (varsayılan 100)
Örnek
curl "https://otpgmail.net/v1/webhook/deliveries?limit=20" \
  -H "Authorization: Bearer og_xxx..."
Örnek yanıt
{
  "success": true,
  "data": [
    {
      "id": "0b7e4c2a-5d1f-4e8b-9a3c-2f6d8e1b4a7c",
      "event": "order.cancelled",
      "orderId": "p8v2n5c1x7z3m9k4",
      "status": "queued",
      "attempts": 1,
      "lastHttpStatus": 503,
      "lastError": "HTTP 503",
      "nextAt": 1760701640,
      "createdAt": 1760701630,
      "deliveredAt": null
    },
    {
      "id": "6f1d2c3b-8a9e-4f70-b1c2-d3e4f5a6b7c8",
      "event": "order.code",
      "orderId": "k3m9x2p7q1w8e5r4",
      "status": "delivered",
      "attempts": 1,
      "lastHttpStatus": 200,
      "lastError": null,
      "nextAt": null,
      "createdAt": 1760700124,
      "deliveredAt": 1760700125
    }
  ]
}
Olası hatalar: UNAUTHORIZED