BetakuryeGeliştirici

Başvuru

Uçlar

Entegratörün kullandığı bütün uçlar. Örnek yanıtlar gerçek API'den alındı; kimlikler örnek değerlerle değiştirildi. Makine okunur tanım: /docs (OpenAPI).

Bu sayfada: Restoranlar · Teklif ve hizmet alanı · Teslimatlar · Adres önerisi · Teslim kanıtı · Ödeme tipleri · Webhook adresleri · Müşteri takibi · Sağlık

Restoranlar

POST/v1/stores#

Restoranı eşleme koduyla bağlar; ikinci çağrı bilgileri günceller.

AlanTürAçıklama
external_store_idzorunlustring ≤80Sizin sisteminizdeki restoran/şube kimliği
pairing_codestringKurye firmasının ürettiği tek kullanımlık kod. İlk kayıtta zorunlu.
namezorunlustringRestoran adı (kuryenin ve firmanın gördüğü)
phonestringRestoran telefonu (kurye arar)
address.textzorunlustringAçık adres
address.lat, address.lngnumberRestoranın konumu. Gönderin: kurye ataması ve süre tahmini buna göre.

Yanıt: ilk kayıt 201, sonraki çağrılar 200. Hatalar: 400 ESLEME_KODU_GEREKLI, 400 ESLEME_KODU_GECERSIZ, 409 BASKA_POS (restoran başka entegratöre bağlı).

Yanıt
{
  "id": "6ef5f915-05c4-4900-9f70-ccf86232d580",
  "external_store_id": "lezzet-bostanli",
  "name": "Lezzet Döner Bostanlı",
  "phone": "02323334455",
  "address_text": "Cemal Gürsel Cad. No:120, Bostanlı, Karşıyaka",
  "lat": 38.4601,
  "lng": 27.0915,
  "status": "ACTIVE",
  "courier_company": {
    "id": "7b1e2a40-3c55-4c7e-9b1a-2f3d4e5f6a7b",
    "name": "Betakurye İzmir"
  },
  "created_at": "2026-10-11T13:20:46.976Z",
  "updated_at": "2026-10-11T13:20:46.976Z"
}

GET/v1/stores#

Kimliğinizle bağladığınız restoranlar, en yeniden eskiye (en çok 500). Başka entegratörün bağladığı restoran listede çıkmaz.

curl
curl https://betakurye.com/v1/stores -H "Authorization: Bearer $TOKEN"

GET/v1/stores/{external_store_id}#

Tek restoran (sizin kimliğinizle).

Bağlı değilse 404 BULUNAMADI.

Teklif ve hizmet alanı

POST/v1/quotes#

Sipariş açmadan: hizmet alanında mı, ne zaman gelir, ücret ne. Kayıt açmaz, kontör düşmez.

AlanTürAçıklama
store.external_store_idzorunlustringRestoran
dropoff.lat, dropoff.lngzorunlunumberTeslim noktası
ready_atISO 8601Paketin hazır olacağı an
scheduled_forISO 8601İleri tarihli teslim anı

serviceable: false ise reason: HIZMET_DISI (mesafe), MAGAZA_PASIF, MAGAZA_KONUMSUZ, KONUM_GECERSIZ (0,0 ya da Türkiye dışı konum). Sipariş açılırken de aynı hesap yapılır: teklifteki ücret ve mesafe siparişe yazılanla aynıdır. fee yalnız kurye firması fiyat tablosu tanımladıysa dolu (KDV hariç). Süreler tahmindir.

curl
curl -X POST https://betakurye.com/v1/quotes -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"store":{"external_store_id":"lezzet-bostanli"},"dropoff":{"lat":38.4701,"lng":27.1015}}'
Yanıt · 200
{
  "serviceable": true,
  "reason": null,
  "distance_m": 1412,
  "road_km": 1.9,
  "max_km": 10,
  "eta_pickup_at": "2026-10-11T13:30:51.117Z",
  "eta_dropoff_at": "2026-10-11T13:38:25.117Z",
  "couriers_on_shift": 1,
  "fee": null,
  "expires_at": "2026-10-11T13:25:51.117Z"
}

GET/v1/delivery-areas#

Restoranlarınızın hizmet alanı: restoran merkezli daire (kuş uçuşu yarıçap).

Yanıt · 200
{
  "items": [
    {
      "store_id": "6ef5f915-05c4-4900-9f70-ccf86232d580",
      "external_store_id": "lezzet-bostanli",
      "name": "Lezzet Döner Bostanlı",
      "center": {
        "lat": 38.4601,
        "lng": 27.0915
      },
      "radius_m": 7407,
      "active": true
    }
  ]
}

Teslimatlar

POST/v1/deliveries#

Sipariş gönderir. Idempotency-Key başlığı zorunlu (8–128 karakter).

AlanTürAçıklama
external_refzorunlustring ≤40Sizin sipariş numaranız. Aynı restoranda benzersiz (409 EXTERNAL_REF_TEKRAR).
store.external_store_idzorunlustringBağladığınız restoran
customer.namestringMüşteri adı
customer.phonestringMüşteri telefonu (kurye arar; firma açtıysa takip SMS'i gider). Getir/Trendyol siparişinde platformun çağrı merkezi numarası
customer.phone_extensionrakam ≤20Platform siparişinde santralde tuşlanacak kod (Getir arama kodu, Trendyol pinCode). Kurye santrali arar, uygulama kodu kendisi tuşlar; müşteriye SMS gitmez
customer.notestring ≤500Müşteri notu (kurye ve restoran görür)
dropoff.textzorunlustringAçık adres
dropoff.directionsstringTarif: kat, daire, zil, yakın yer
dropoff.neighborhood, district, citystringMahalle, ilçe, il (adres çözümüne yardım eder)
dropoff.lat, dropoff.lngnumberVerilirse sipariş hemen kurye arar (QUEUED); yoksa RECEIVED. Konum yoksa alanı göndermeyin: 0,0 ve Türkiye dışı konum yok sayılır (RECEIVED, adres çözümü)
payment.typezorunlukodÖdeme tipleri listesinden
payment.amount_duezorunlunumberKapıda alınacak tutar (TL)
payment.prepaidbooleantrue: ödendi, kapıda para alınmaz
payment.subtotal, payment.discountnumberAra toplam, indirim (gösterim)
items[]dizi ≤200{ name, quantity, total, code? }: kurye restoranda paketi bununla kontrol eder. quantity ondalık olabilir (0.5 porsiyon; en çok 3 basamak)
package_countinteger 1–20Paket adedi (varsayılan 1)
ready_atISO 8601Paketin hazır olacağı an
scheduled_forISO 8601İleri tarihli teslim anı (en çok 7 gün)
require_pinbooleanTeslim PIN'i iste; yanıtta delivery_pin döner
notesstring ≤500Restoranın kuryeye notu
origin_channelstring ≤20Siparişin kaynağı (ör. pos, yemeksepeti, getir, trendyol, telefon)
testbooleanEntegrasyon denemesi: sipariş kaydedilir, created ve cancelled webhook'ları gider, ama kuryeye düşmez, hemen iptal edilir; kontöre ve raporlara girmez

Yanıt: 201 (yeni), 200 (aynı anahtar + aynı gövde tekrarı). Hatalar:

  • 409 IDEMPOTENCY_CAKISMA: aynı anahtar farklı gövdeyle.
  • 409 EXTERNAL_REF_TEKRAR: bu restoranda aynı numarayla sipariş var; error.details.delivery_id mevcut siparişin kimliği.
  • 409 MAGAZA_PASIF: restoran askıda ya da kapalı.
  • 422 HIZMET_DISI: adres kurye firmasının hizmet alanı dışında; error.details = { road_km, max_km }.
  • 404 MAGAZA_YOK: restoran bağlı değil.
Yanıt · 201
{
  "id": "c06218cb-638d-488d-a5d2-e368e9c3bd74",
  "external_ref": "SM-48213",
  "store_id": "6ef5f915-05c4-4900-9f70-ccf86232d580",
  "status": "QUEUED",
  "version": 1,
  "courier": null,
  "dropoff": {
    "text": "Şehitler Cad. No:12 D:4 · Eczanenin üstü",
    "lat": 38.4701,
    "lng": 27.1015,
    "source": "pos",
    "ref": null,
    "candidates": null,
    "district": "Karşıyaka",
    "neighborhood": "Bostanlı",
    "city": "İzmir"
  },
  "payment": {
    "type": "NAKIT",
    "amount_due": 380,
    "collected_type": null,
    "collected_parts": null,
    "subtotal": 420,
    "discount": 40
  },
  "customer": {
    "name": "Ayşe Demir",
    "phone": "+905321234567",
    "phone_extension": null,
    "note": "Zili çalmayın"
  },
  "items": [
    {
      "name": "Adana Dürüm",
      "quantity": 2,
      "total": 360
    },
    {
      "name": "Ayran",
      "quantity": 2,
      "total": 60
    }
  ],
  "scheduled_for": null,
  "notes": null,
  "origin_channel": "pos",
  "package_count": 1,
  "prepaid": false,
  "test": false,
  "fee": null,
  "distance_m": 1412,
  "road_km": 1.9,
  "tracking_url": "https://betakurye.com/t/NwnC4m6V8KVOUJNbXW9CUA",
  "eta_pickup_at": "2026-10-11T13:30:49.068Z",
  "eta_dropoff_at": "2026-10-11T13:38:23.068Z",
  "ready_at": null,
  "assigned_at": null,
  "picked_up_at": null,
  "delivered_at": null,
  "cancelled_at": null,
  "returned_at": null,
  "delivery_pin": "2870",
  "pin_required": true,
  "failure_reason": null,
  "loss": null,
  "cancel_reason": null,
  "unassigned_alert_at": null,
  "created_at": "2026-10-11T13:20:49.044Z",
  "updated_at": "2026-10-11T13:20:49.044Z"
}

Yanıt alanları

AlanTürAçıklama
iduuidBetakurye teslimat kimliği (diğer uçlarda bunu kullanın)
status, versionstring, integerDurum ve her değişiklikte artan sürüm
couriernesne | nullAtanınca: name, phone, phone_masked, plate, lat, lng, location_at, heading (pusula açısı, derece), speed_mps (hız, m/sn)
tracking_urlstringMüşterinin canlı takip sayfası
eta_pickup_at, eta_dropoff_atISO 8601 | nullTahmini alış ve teslim
delivery_pin, pin_requiredstring | null, booleanTeslim PIN'i
payment.collected_typekod | nullTeslimde kuryenin tahsil ettiği tip (parçalı ödemede en büyük parça)
payment.collected_parts{ type, amount }[] | nullParçalı ödeme (ör. nakit + kart); tek tipte null
dropoff.candidatesdizi | nullKoordinatsız siparişte adres adayları: ref, text, lat, lng, score, distance_m (alanlar Adres önerisi ile aynı)
failure_reason, cancel_reasonstring | nullBaşarısız/iade sebebi, iptal sebebi
loss{ kind, reported_at, decided } | nullZayi bildirimi: HASAR (hasar gördü) ya da KAYIP; kararı kurye firması verir
fee{ amount, currency, vat_included } | nullRestorana uygulanacak ücret (kurye firmasının fiyat tablosu; restorana özel tarife tanımlıysa o; açılıştaki mesafe; KDV hariç). Tablo ya da konum yoksa null
distance_m, road_kminteger | null, number | nullRestoran → teslim adresi kuş uçuşu (m) ve tahmini yol (km)
customer.phone_extensionstring | nullPlatform santrali dahili kodu
testbooleanEntegrasyon denemesiyle açıldı
*_atISO 8601 | nullready_at, assigned_at, picked_up_at, delivered_at, cancelled_at, returned_at, created_at, updated_at

GET/v1/deliveries/{id}#

Tek teslimat. Başka entegratörün teslimatı 404 döner.

curl
curl https://betakurye.com/v1/deliveries/c06218cb-638d-488d-a5d2-e368e9c3bd74 -H "Authorization: Bearer $TOKEN"

GET/v1/deliveries#

Değişen teslimatlar, eskiden yeniye (updated_at). Webhook'u kaçırdığınızda eşitleme için.

AlanTürAçıklama
sinceimleçÖnceki yanıtın next_cursor değeri
limit1–200Varsayılan 100
statusvirgüllü listeör. QUEUED,ASSIGNED
fromISO 8601Bu andan sonra değişenler
created_from, created_toISO 8601Oluşturulma aralığı
external_refstringKendi sipariş numaranızla arama: zaman aşımından sonra "sipariş açıldı mı" sorusu. Verilince zaman penceresi uygulanmaz
external_store_idstringRestorana göre daraltma (aynı numara iki restoranda olabilir)
curl
curl "https://betakurye.com/v1/deliveries?external_ref=S-10234&external_store_id=lezzet-bostanli" -H "Authorization: Bearer $TOKEN"

Yanıt { items, next_cursor, has_more }. has_more false olana kadar since=next_cursor ile devam edin. Bozuk imleç 400 IMLEC_GECERSIZ.

PATCH/v1/deliveries/{id}#

Paket kuryeye verilmeden önce değişiklik.

AlanTürAçıklama
dropoffnesneYeni adres (koordinatla gönderirseniz RECEIVED → QUEUED)
ready_atISO 8601 | nullHazır olma anı
scheduled_forISO 8601 | nullİleri tarih; yalnız teklif çıkmadan önce (409 PLAN_DEGISEMEZ)
notesstring | nullKuryeye not
customer.name, customer.phonestringMüşteri bilgisi
customer.phone_extensionrakam | nullSantral dahili kodu; null kaldırır

Paket kuryedeyse 409 KURYE_ALDI. Adres değişince mesafe ve ücret yeniden hesaplanır; hizmet alanı dışı adres 422 HIZMET_DISI.

POST/v1/deliveries/{id}/cancel#

Paket kuryeye verilmeden iptal. Kontör düşmez.

curl
curl -X POST https://betakurye.com/v1/deliveries/<id>/cancel -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"reason":"Müşteri vazgeçti"}'

Hatalar: 409 KURYE_ALDI (paket kuryede), 409 SON_DURUM (zaten bitmiş).

Adres önerisi

GET/v1/address/search#

Adres metninden kapı numarası düzeyinde koordinat önerisi. Koordinatsız (RECEIVED) siparişin adresini kullanıcıya seçtirmek için.

AlanTürAçıklama
qzorunlustring 3–200Adres metni (sorgu dizesinde, URL kodlu)
limitinteger 1–10En çok kaç öneri (varsayılan 5)
lat, lngnumberYakınlık için referans nokta: restoranın konumu. Verilirse her öneride distance_m döner
curl
curl -G https://betakurye.com/v1/address/search -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "q=Şehitler Cad. No:12 Bostanlı Karşıyaka" -d limit=3 -d lat=38.4601 -d lng=27.0915
Yanıt · 200
{
  "query": "Şehitler Cad. No:12 Bostanlı Karşıyaka",
  "ms": 193,
  "candidates": [
    {
      "ref": "803558",
      "text": "BOSTANLI Mah. ŞEHİTLER No:12",
      "lat": 38.457725329475856,
      "lng": 27.099004779788668,
      "score": 0.6,
      "distance_m": 706.1
    }
  ]
}
AlanTürAçıklama
refstringAdres kaydının kimliği
textstringÖnerilen adres (mahalle, cadde/sokak, kapı no)
lat, lngnumberKapının koordinatı
scorenumber 0–1Eşleşme puanı. Sıralama içindir, eşik değildir: yüksek puan doğru adres demek değildir
distance_mnumberReferans noktaya kuş uçuşu uzaklık (m); lat/lng verilmediyse yok
msintegerAramanın süresi (milisaniye)

Teslim kanıtı

GET/v1/deliveries/{id}/proofs#

Kuryenin kapıda çektiği fotoğrafların listesi.

Yanıt · 200
{
  "items": [
    {
      "id": "5d1c2b3a-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
      "kind": "PHOTO",
      "mime": "image/jpeg",
      "size": 184213,
      "lat": 38.47011,
      "lng": 27.10148,
      "created_at": "2026-10-11T13:41:02.004Z",
      "url": "/v1/deliveries/c06218cb-638d-488d-a5d2-e368e9c3bd74/proofs/5d1c2b3a-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
    }
  ]
}

GET/v1/deliveries/{id}/proofs/{proofId}#

Fotoğrafın kendisi (Bearer ile; içerik türü image/jpeg, png ya da webp).

curl
curl -o teslim.jpg https://betakurye.com/v1/deliveries/<id>/proofs/<proofId> -H "Authorization: Bearer $TOKEN"

Ödeme tipleri

GET/v1/payment-types#

Kodlu ödeme listesi: { no, kod, ad, sinif }.

Liste ve açıklama: Ödeme tipleri.

Webhook adresleri

POST/v1/webhooks#

Adres kaydı; secret yalnız bu yanıtta.

AlanTürAçıklama
urlzorunluhttps URLOlayların gönderileceği adres
event_typesdiziVarsayılan: courier_location dışındaki bütün delivery.* olayları
descriptionstring ≤200Not

Kimlik başına en çok 5 aktif adres (409 ABONELIK_SINIRI).

GET/v1/webhooks#

Adresleriniz (secret dönmez). failing_since: aralıksız hata başladığı an.

DELETE/v1/webhooks/{id}#

Adresi kapatır; bekleyen gönderimler iptal edilir. 204.

POST/v1/webhooks/{id}/rotate#

Yeni secret üretir (eskisi hemen geçersiz). Yanıt kayıt yanıtıyla aynı biçimde.

POST/v1/webhooks/{id}/test#

Adrese webhook.test olayı gönderir. 202 { event_id }.

Müşteri takibi

GET/v1/public/tracking/{anahtar}#

Kimlik istemez; tracking_url sayfasının veri ucu. Kendi uygulamanızda takip göstermek isterseniz kullanın.

Kişisel veri en az: telefon numarası, müşteri adı ve adres metni yok; kurye yalnız adıyla (courier.first_name), konumu yalnız paket kuryedeyken. Anahtar yoksa 404 TAKIP_YOK; teslim/iptalden 2 saat sonra 410 TAKIP_KAPANDI. Dakikada 60 istek.

Sağlık

GET/healthz#

Kimlik istemez. API sürümü ve bağımlılıkların durumu.

Yanıt · 200
{
  "ok": true,
  "version": "2026-10-10",
  "db": "ok",
  "redis": "ok"
}