Yonga.io Türkiye EV Şarj — API ve MCP Referansı

Tek sayfalık referans — Yonga.io Türkiye EV Şarj Verisi platformu için: herkese açık REST API (Scramble OpenAPI dışa aktarımı /docs/api.json, v1.1.6) ve MCP (Model Context Protocol) sunucusu. Türkiye EV Şarj İstasyonu Verisi — 16.000+ faal istasyon · 180+ ağ · 81 il · 7 bölge. Sayılar alt sınırdır: veri EPDK kaynağından günlük güncellenir; kesin değerleri meta.pagination.total_results alanından okuyun. Son güncelleme: 12 Ekim 2026. /mcp artık hesabın access mcp iznini gerektiriyor ve Claude.ai / ChatGPT bağlayıcıları için OAuth ile giriş kazanıyor — bkz. §6.1 ve Docs/62. İstasyon uç noktalarındaki fields parametresi artık virgülle ayrılmış seyrek bir liste kabul ediyor ve fields=summary artık sockets dizisini döndürmüyor — bkz. §5.3 ve Docs/60. Hizmet şekli 3 Eylül 2026’da bir görünürlük filtresi olmaktan çıktı ve is_public alanı service_type olarak yeniden adlandırıldı — bkz. §4 ve Docs/55.


İçindekiler

  1. Genel Bakış
  2. Temel URL’ler
  3. Kimlik Doğrulama
  4. API Kuralları
  5. REST API Uç Noktaları
  6. MCP Sunucusu
  7. Hata Referansı

1. Genel Bakış

Yonga.io, Türkiye EV şarj verilerini ve ülkenin tam idari coğrafyasını sunar:

Alan İçerik
Şarj istasyonları 16.000’i aşkın faal istasyon (pasifleşen satırlar station_status=inactive ile sorgulanabilir); EPDK kayıt verileri, koordinatlar, adres, hizmet şekli (halka açık / özel), yeşil bayrağı, durum, editoryal açıklama ve soket bazında detay (tip, standart, güç kW)
Şarj ağları 180+ operatör (ZES, Eşarj, Trugo, …); şirket bilgileri, iletişim detayları, uygulama/web URL’leri ve AC/DC fiyatlandırma
Coğrafya 7 bölge → 81 il → 992 ilçe → ~49.000 mahalle; koordinatlar, sınırlar ve GeoJSON poligonlar
Olaylar Son N günde eklenen veya pasifleşen istasyon ve ağların kayan değişim günlükleri

Aynı veri iki şekilde sunulur:

  • REST API — /api altında HTTPS üzerinden JSON, §5 bölümünde belgelenmiştir.
  • MCP sunucusu — AI ajanları (Claude, Cursor, …) için POST /mcp adresinde Streamable HTTP, §6 bölümünde belgelenmiştir.

Her ikisi de aynı yanıt zarfını ve Sanctum bearer token’larını kullanır; /mcp ayrıca sohbet uygulaması bağlayıcılarından gelen OAuth 2.1 token’larını kabul eder (§6.2).

/mcp üzerinde değişenler (12 Ekim 2026)

REST API değişmedi. MCP uç noktasında:

Kaldırılan / değişen Yerine
Okuma yeteneği taşıyan her token /mcp’yi çağırabiliyordu Hesabın ayrıca access mcp iznine sahip olması gerekir (her kademe rolü bu izni taşır). İzin yoksa geçerli bir token ile bile /mcp 403 döner; rol kaldırıldığında canlı token bir sonraki çağrıda devre dışı kalır
/mcp’den gelen 401, WWW-Authenticate: Bearer realm="mcp", error="invalid_token" taşıyordu OAuth kapalıyken aynı. OAuth açıkken keşif belgesini gösterir: Bearer realm="mcp", resource_metadata="https://dash.yonga.io/.well-known/oauth-protected-resource/mcp"
— Yeni (kademeli açılıyor): Claude.ai ve ChatGPT özel bağlayıcıları için OAuth 2.1 + PKCE — URL’yi girin, giriş yapın, onaylayın; kopyalanacak token yok. Bkz. §6.2
— DELETE /mcp bir Streamable HTTP oturumunu sonlandırır (Laravel MCP 1.0)

v1.1.6 ile değişenler

Kaldırılan / değişen Yerine
fields=summary satırındaki sockets[] Kaldırıldı. fields=full kullanın ya da seyrek listede adlandırın: fields=…,sockets. sockets_summary içindeki sayılar değişmedi
— Yeni: İstasyon uç noktalarında fields, virgülle ayrılmış seyrek liste kabul ediyor — bkz. §5.3
— Yeni: find_nearby_stations MCP aracında fields artık ayarlanabilir (önceden summary’ye sabitlenmişti)

Bir summary satırı hep hem sockets_summary’yi hem de tüm soket satırlarını taşıyordu — 50 satırlık bir sayfada onlarsız 20 KB yerine 73 KB — oysa bu belge, uç noktanın PHPDoc’u ve biçimlendiricinin kendi docblock’u onu sade bir satır diye tarif ediyordu. Soket satırları artık orada değil. Bkz. Docs/60.

v1.1.5 ile değişenler

Daha eski bir entegrasyondan geliyorsanız bu kırıcı değişikliklere dikkat edin:

Kaldırılan / değişen Yerine
GET /map/stations latitude/longitude/radius ile GET /charging-stations, ya da il pinleri için GET /charging-stations/map
GET /map/nearby GET /charging-stations?latitude=…&longitude=…&radius=…&fields=summary
GET /map/clusters (kaldırıldı — /charging-stations/map çıktısını istemci tarafında kümeleyin)
GET /districts/{citySlug} takma adı GET /cities/{citySlug}/districts
İstasyon listesindeki meta.statics meta.filters (uygulanan coğrafi/arama bağlamının yankısı)
Ağlarda populate=page / populate=stations GET /charging-networks/{slug}/stations, GET /charging-networks/{slug}/pricing
/cities listesindeki şarj toplamları Toplamlar yalnızca il detayında (GET /cities/{slug})
search_term min. 2 karakter Min. 3 karakter (artık yedi sütuna bakıyor)
— Yeni: /regions, /regions/{slug}, /charging-stations/slugs, /charging-stations/map, /charging-networks/{slug}/pricing, /charging-networks/{slug}/stations, /events/*

2. Temel URL’ler

Ortam REST API MCP
Üretim https://dash.yonga.io/api https://dash.yonga.io/mcp
Yerel / geliştirme https://dash.yonga.local/api https://dash.yonga.local/mcp

Bu belgedeki tüm REST yolları API temel URL’sine göredir (ör. GET /charging-stations ⇒ GET https://dash.yonga.io/api/charging-stations).

Etkileşimli OpenAPI dokümantasyonu (Scramble) Laravel uygulamasında /docs/api adresinde sunulur; ham spesifikasyon /docs/api.json dosyasıdır.


3. Kimlik Doğrulama

API, Laravel Sanctum bearer token kullanır (Authorization: Bearer <token>, OpenAPI şeması: http / bearer / format sanctum).

  • GET /status herkese açıktır; diğer tüm uç noktalar token gerektirir.
  • Token’lar yetenekler taşır ve her yol grubu ilgili yeteneği zorunlu tutar:
Yetenek Erişim verdiği uç noktalar
stations:read /charging-stations*
networks:read /charging-networks*
map:read /regions*, /cities*
stats:read /events/*
tier:<free|basic|pro|beta|enterprise> Bilgilendirme amaçlı — sorgu limiti bu yetenekten değil, hesabın rolünden çözümlenir

POST /mcp dört okuma yeteneğinden herhangi birini (veya OAuth kapsamı mcp:use) gerektirir ve hesabın access mcp iznine sahip olması gerekir — bkz. §6.1.

POST /login — token alma

curl -X POST https://dash.yonga.io/api/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"***","device_name":"my-client"}'
{
  "success": true,
  "token": "19|w49cgKFBEv0…",
  "user": { "id": 1, "name": "…", "email": "[email protected]" },
  "abilities": ["tier:pro", "stations:read", "networks:read", "map:read", "stats:read"]
}

İsteğe bağlı abilities[] dizisi, hesabın izinli kümesini yalnızca daraltabilir — kümenin dışında bir yetenek istemek 422 döndürür. Hatalı kimlik bilgileri de 422 döner. Giriş, e-posta + IP başına dakikada 5 istek ile sınırlandırılmıştır.

Dönen token değerini her sonraki istekte kullanın:

curl https://dash.yonga.io/api/charging-stations \
  -H "Authorization: Bearer <token>"

GET /me — mevcut token’ı inceleme

{ user: { id, name, email, roles[] }, abilities[], authenticated: true } döndürür.

POST /logout — mevcut token’ı iptal etme

{ success: true, message: "Token revoked successfully" } döndürür.


4. API Kuralları

Sorgu limitleri

Limitler API kademesine göre uygulanır ve kademe, hesabın rolünden çözümlenir. İki limit aynı anda geçerlidir: saatlik değer kotayı, dakikalık değer ise ani yük tavanını belirler.

Kademe Saatlik Dakikalık
kimliksiz 60 20
free 100 20
basic 1.000 60
pro 10.000 300
beta 20.000 500
enterprise 100.000 2.000

Tüm /api/* uç noktaları ve /mcp için geçerlidir. Limit aşıldığında yanıt, standart hata zarfıyla 429 döner:

{
  "data": null,
  "error": {
    "status": 429,
    "name": "TooManyRequestsError",
    "message": "Rate limit exceeded for your API tier. Retry after the number of seconds given in the Retry-After header.",
    "details": { "retry_after": 37 }
  }
}

Her yanıtta X-RateLimit-Limit ve X-RateLimit-Remaining başlıkları bulunur; 429 yanıtları ayrıca saniye cinsinden Retry-After taşır. İstemcilerin sabit bir bekleme süresi yerine bu başlıklara göre geri çekilmesi önerilir.

Yanıt zarfı (Strapi uyumlu)

Her başarılı yanıt aynı zarfta sarılır:

{
  "data": [ ... ],           // detay uç noktalarında nesne, listelerde dizi
  "meta": {
    "pagination": {
      "page": 1,
      "limit": 25,
      "total_pages": 8,
      "total_results": 187
    }
  }
}

Uç noktaya göre meta ayrıca filters, city, district, total, web_status, days, group_by veya total_groups taşıyabilir. Üç uç nokta sayfalanmaz ve meta.pagination içermez: /charging-stations/slugs, /charging-stations/map ve her iki /events/* günlüğü.

Hatalar hata zarfı kullanır (§7 bölümüne bakın):

{
  "data": null,
  "error": { "status": 404, "name": "NotFoundError", "message": "...", "details": { } }
}

Sayfalama

Parametre Varsayılan Notlar
page 1 1 tabanlı sayfa numarası
limit 25 (ağlar, bölgeler, iller) / 50 (istasyonlar, ilçeler, mahalleler) İstasyon/ağ/bölge/il için maks. 100, ilçe/mahalle için 200; üzerinde 422

populate — ilişki yükleme

Virgülle ayrılır; detay uç noktalarında ve iki coğrafya listesinde geçerlidir. Listelenmeyen değerler yok sayılır.

Uç nokta populate değerleri
GET /regions cities
GET /regions/{slug} cities, polygon
GET /cities polygon
GET /cities/{slug} districts, polygon
GET /cities/{citySlug}/districts polygon
GET /cities/{citySlug}/districts/{districtSlug} polygon

Yukarıdaki uç noktalar, istenmeyen alanları yanıttan çıkarmaz; null olarak döndürür — yani populate yanıtın şeklini değiştirmez.

GET /regions, populate ne isterse istesin poligon döndürmeyen tek listedir — bölge sınırları yalnızca detay uç noktasındadır. Diğerlerinde polygon erişilebilirlik değil ağırlık nedeniyle isteğe bağlıdır: bir il poligonu ~50 KB’dır, dolayısıyla GET /cities?limit=100&populate=polygon birkaç megabaytlık bir yanıttır. Yalnızca sınırları çizecekseniz isteyin.

Şarj ağları hiçbir populate değeri kabul etmez; bunun yerine /stations ve /pricing alt yollarını kullanın.

Tanımlayıcılar ve slug’lar

  • Slug’lar Türkçe normalleştirilmiştir (ç→c, ş→s, ı→i, …), örn. Eşarj → esarj, Çankaya → cankaya.
  • İstasyon detayı aynı yol parametresi üzerinden id, slug veya EPDK id kabul eder.
  • Ağ detayı id veya slug; il/bölge detayı slug, plaka_id, tkgm_id veya sayısal id kabul eder.
  • Bir slug 404 döndürürse tahmin etmeyin — liste uç noktaları (search / search_term) ile çözün.

Arama (search_term)

/charging-stations üzerindeki search_term (min. 3, maks. 100 karakter) istasyon adı, ağ adı ve şirket adı, mahalle, ilçe, il, sokak adresi ve EPDK id sütunlarını kapsar. Eşleştirme büyük/küçük harf ve aksan duyarsızdır ve her iki yönde çalışır: kadikoy → Kadıköy ve tersi. Boşluk, terimi en fazla beş parçaya böler ve her parçanın bir yerde eşleşmesi gerekir — "ankara zes" (Ankara’da) VE (ZES işletmesinde) demektir.

Sonuçlar eşleşme kalitesine göre sıralanır: tam ad veya EPDK id → ad ön eki → ağ → mahalle/ilçe/il → ad içinde geçen parça → adres. latitude/longitude verildiğinde bunun yerine mesafe sıralaması korunur.

/charging-networks üzerindeki search_term aynı katlamayı ad, şirket adı ve slug’a uygular (minimum uzunluk yok). Coğrafya uç noktalarındaki search ise Türkçe normalleştirilmiş bir ad filtresidir.

Varsayılan görünürlük filtreleri

İstasyon uç noktaları varsayılan olarak yalnızca faal istasyonları döndürür (station_status=active) — 30 Ağustos 2026’da veri setindeki 17.744 satırın 16.751’i. Yayınlanan tüm toplamlar aynı filtreyi kullanır: bir ilin ya da ağın total_stations, soket sayıları ve total_power_kw değerleri yalnızca bu kümeyi kapsar; dolayısıyla aynı yer için liste toplamı ile coğrafya toplamı birbiriyle uyuşur. Her ikisinin de dışında kalan tek küme, EPDK kaydından düşen istasyonlardır (station_status=inactive) — 993 satır.

Hizmet şekli bir görünürlük filtresi değildir. Hem halka açık istasyonlar (EPDK HALKA_ACIK) hem de özel hizmet verenler (OZEL — bir şirket filosu, bir depo) yayınlanır ve sayılır. Tek bir türe daraltmak için service_type=public|private kullanın; ikisini birlikte almak için parametreyi hiç göndermeyin. 3 Eylül 2026’ya kadar varsayılan filtre ek olarak is_public=true koşulunu da içeriyordu ve bu, 3.719 faal istasyonu dışarıda bırakıyordu; bkz. Docs/55.

Üç uç nokta yalnızca halka açık istasyonlarda kalır ve service_type parametresi almaz; çünkü haritadaki bir iğne ya da dizine eklenen bir sayfa, sürücüye “burada şarj edebilirsin” sözü verir: il harita iğnesi akışı (/charging-stations/map), MCP üzerindeki find_nearby_stations ve slug/site haritası akışı (/charging-stations/slugs). Bu nedenle bir ilin iğne sayısı total_stations değerinden düşüktür ve iki sayının ikisi de doğrudur.

web_status (published | draft | review) bir görünürlük değil editoryal kapıdır: published, açıklamanın hazır olduğu ve bir editörün genel sayfayı onayladığı anlamına gelir. İstasyon uç noktaları bunu örtük olarak filtrelemez — istediğinizde siz geçirirsiniz. Tek istisna, sorusu tam olarak bu olduğu için varsayılanı web_status=published olan /charging-stations/slugs’tır.

İki serileştirme tuhaflığı

  • service_type alanı "public" veya "private" olarak, yalnızca tam satırlarda döner — fields=full liste satırları ve istasyon detayı. Sade şekiller (fields=summary, harita iğnesi akışı, slug akışı) ne bu alanı ne de is_public’i taşır. Kullanımdan kaldırılan is_public alanı bir sürüm boyunca onun yanında yayınlanır, sonra kaldırılır — yeni entegrasyonlar service_type okumalı.
  • İstasyon satırlarında is_public ve is_green_station JSON boolean’ı değil, "true" / "false" metinleri olarak döner. Karşılaştırmanızı buna göre yapın. Girdi olarak gerçek boolean kabul edilir.
  • Koordinatlar virgüllü ondalık ayırıcı kabul eder (39,9387 → 39.9387); istasyon satırlarında metin ("34.95670000"), coğrafya satırlarındaki coordinates/bounds altında float olarak döner.

Önbellek

Yanıtlar grup bazında 24 saat önbelleklenir (api:stations, api:networks, api:geo, api:events) ve her yazma işleminde temizlenir; bu nedenle veri değişikliği anında görünür — TTL yalnızca uygulama dışında yapılan değişikliklerin bayatlığını sınırlar.


5. REST API Uç Noktaları

Belirtilmedikçe tüm uç noktalar GET metodudur ve Authorization: Bearer <token> gerektirir.

Hızlı indeks:

Metod Yol Yetenek Amaç
GET /status (herkese açık) Sağlık kontrolü
POST /login (herkese açık) Sanctum token verme
GET /me (her token) Mevcut kullanıcı + token yetenekleri
POST /logout (her token) Token iptali
GET /charging-networks networks:read Ağ operatörlerini listele/ara
GET /charging-networks/{slug} networks:read Ağ detayı
GET /charging-networks/{slug}/pricing networks:read Yalnızca ağ tarifeleri
GET /charging-networks/{slug}/stations networks:read Tek bir ağın istasyonları
GET /charging-stations stations:read Liste / filtre / arama / yarıçap / toplulaştırma
GET /charging-stations/map stations:read Bir ilin tüm harita pinleri, sayfalamasız
GET /charging-stations/slugs stations:read SSG/site haritası için yayınlanmış sayfa slug akışı
GET /charging-stations/{slug} stations:read İstasyon detayı (id / slug / EPDK id)
GET /regions map:read 7 bölgeyi listele
GET /regions/{slug} map:read Bölge detayı + şarj toplamları
GET /cities map:read 81 ili listele
GET /cities/{slug} map:read İl detayı + şarj toplamları + en büyük ağlar
GET /cities/{citySlug}/districts map:read Bir ilin ilçeleri
GET /cities/{citySlug}/districts/{districtSlug} map:read Bir ilçenin mahalleleri
GET /events/stations-changelog stats:read N günde eklenen / pasifleşen istasyonlar
GET /events/networks-changelog stats:read N günde eklenen / pasifleşen ağlar

5.1 Servis

GET /status — sağlık kontrolü (herkese açık)

Ne veritabanına ne de önbelleğe dokunur; bu nedenle onlar bozukken de ayakta kalır.

{ "status": 200, "message": "Yonga API is working", "version": "1.1.5", "timestamp": "2026-08-30T20:20:20.482472Z" }

5.2 Şarj Ağları

GET /charging-networks — ağ operatörlerini listele

Sorgu parametreleri

Parametre Tip Varsayılan Açıklama
page int 1 Sayfa numarası
limit int 25 Sayfa başına satır (maks. 100)
search_term string — Ad, şirket adı ve slug üzerinde anahtar kelime araması (çift yönlü aksan duyarsız)
network string — Tam ağ slug’ına göre filtre (ör. zes)
type string — Ağ tipi/kategorisi (ör. public)
hasPrices bool — Yalnızca en az bir fiyat alanı dolu olan ağlar
web_status string — published | draft | review
data_status string — Dahili veri hattı durumu

İstasyon sayısına göre azalan, sonra slug’a göre sıralanır.

Yanıt — data[] öğesi

Alan Tip Notlar
id int
name, slug string Slug Türkçe normalleştirilmiştir
company_name, description, type string|null
phone, email, address_street string|null İletişim bilgileri
logo_url, linkedin_url, website_url, pricing_url string|null
app_url_ios, app_url_android, app_url_huawei string|null Mobil uygulamalar
fiyat_ac, fiyat_dc_fast, fiyat_dc_ultra_fast, fiyat_desc string|null AC / DC hızlı / DC ultra hızlı fiyatlandırma (TL/kWh) + açıklama
data_status, error_message string|null Veri hattı durumu
total_stations, totalSockets, total_sockets, total_ac_sockets, total_dc_sockets, total_power_kw number Her iki hizmet şeklindeki faal istasyonlar üzerinden toplu istatistikler (§4). total_sockets ile totalSockets aynı sayının iki adıdır — camelCase anahtar eski tüketiciler için korunuyor ve kaldırılacak
created_at, updated_at string ISO-8601
published_at string|null web_status=published ise updated_at, değilse null

meta.pagination: page, limit, total_pages, total_results.

curl "https://dash.yonga.io/api/charging-networks?hasPrices=1&limit=50" \
  -H "Authorization: Bearer <token>"

GET /charging-networks/{slug} — ağ detayı

Parametre Konum Açıklama
slug path Sayısal id veya slug (ör. zes, esarj)

Liste öğesiyle aynı alanlar, data_status hariç. Bilinmeyen tanımlayıcı için 404 hata zarfı.

GET /charging-networks/{slug}/pricing — yalnızca tarifeler

Fiyat karşılaştırması için bilinçli olarak küçük tutulmuş bir yanıt:

{
  "data": {
    "id": 179, "name": "zes", "slug": "zes",
    "fiyat_ac": "8.99",
    "fiyat_dc_fast": "10.99",
    "fiyat_dc_ultra_fast": "12.99",
    "fiyat_desc": "Prices are valid from 21.02.2025 …",
    "hasPrices": true
  }
}

GET /charging-networks/{slug}/stations — bir ağın istasyonları

İstek ve yanıt yapısı GET /charging-stations ile birebir aynıdır — network dışındaki tüm istasyon filtreleri geçerlidir; network URL tarafından sabitlenir ve gönderilse bile yok sayılır. Ağ bilinmiyorsa 404.

curl "https://dash.yonga.io/api/charging-networks/zes/stations?city=ankara&socket_type=DC&limit=100" \
  -H "Authorization: Bearer <token>"

5.3 Şarj İstasyonları

GET /charging-stations — liste, arama, yarıçap, toplulaştırma

Tek uç nokta dört modu kapsar: filtreli liste, anahtar kelime araması, “yakınımda” yarıçap araması ve ağ bazında toplulaştırma.

Sorgu parametreleri

Parametre Tip Varsayılan Açıklama
page int 1 Sayfa numarası
limit int 50 Sayfa başına satır (maks. 100)
fields string full full | summary | virgülle ayrılmış seyrek liste — yanıt şekli, bkz. aşağıdaki bölüm
city string — İl slug’ı, örn. istanbul
district string — İlçe slug’ı, örn. kadikoy
network string — Ağ operatörü slug’ı, örn. zes
connector_type string — CCS2 | Type2 | CHAdeMO
socket_type string — AC | DC
power_min / power_max number — Soket güç aralığı kW cinsinden (ör. hızlı DC için power_min=50)
latitude / longitude number — Merkez nokta — distance (km) ekler ve en yakından sıralar
radius number 10 Arama yarıçapı km, 0.1–200 (yalnızca koordinatla birlikte)
search_term string — Anahtar kelime araması, min. 3 karakter (§4)
service_type string — public (HALKA_ACIK) veya private (OZEL). İkisi için boş bırakın
is_public bool — Kullanımdan kaldırıldı, service_type için takma ad: 1 → yalnızca halka açık, 0 → yalnızca özel. Dikkat: 0 eskiden ikisini birlikte döndürüyordu, artık daraltıyor. Bir sürüm sonra kaldırılacak
is_green_station bool — Yalnızca yenilenebilir/yeşil enerjili istasyonlar
station_status string active active | inactive
web_status string — published | draft | review
data_status string — Dahili veri hattı durumu
group_by string — network — toplulaştırma modu (aşağıya bakın)

Koordinat verilmediğinde sonuçlar web_status azalan, sonra en yeni olacak şekilde sıralanır — search_term varsa arama alaka düzeyine göre.

Yanıt — data[] öğesi (fields=full)

Alan Tip Notlar
id int
station_epdk_id, epdk_id string EPDK kayıt tanımlayıcıları (ör. ŞRJ/18971, srj18971)
name, slug string
network object|null id, name, slug, company_name, phone, email, website_url
city object|null id, name, slug, plaka, tkgm_id, osm_relation_id, longitude, latitude
district, mahalle object|null id, name
address string Tam sokak adresi
longitude, latitude string|null Koordinatlar (metin biçimli ondalık)
phone, email string|null Ağ iletişimi, yoksa istasyonun kendi bilgisi
service_type string "public" / "private" — EPDK hizmet şekli
is_public, is_green_station string "true" / "false" — §4. is_public, service_type için kullanımdan kaldırılmış takma addır
notes string|null Genel sayfada gösterilen editoryal/AI üretimi Türkçe açıklama
station_status, error_message string|null Durum alanları
yonga_url string|null Kanonik genel sayfa URL’si — yalnızca web_status=published iken, aksi halde null
sockets array id, socket_number, socket_type (AC/DC), socket_standard (CCS2/AC_TYPE2/…), power_kw, status, socket_status, error_message, created_at, updated_at
distance number|null İstenen merkezden km; koordinat yoksa null
created_at, updated_at string ISO-8601

Yanıt — data[] öğesi (fields=summary)

id, name, slug, longitude, latitude, distance, network {name, slug}, city {name, slug}, district {name, slug}, is_green_station, sockets_summary { total, ultra_fast, very_fast, fast, slow }.

Soket hız kovaları: ultra_fast ≥ 200 kW · very_fast 100–199 · fast 23–99 · slow 3–22.

Bir summary satırı soket sayılarını taşır, soket satırlarını değil. Soket bazında detay gerekiyorsa fields=full isteyin ya da seyrek listede sockets alanını adlandırın.

fields — yanıt şekli

Üç biçim, en ucuzdan başlayarak:

Biçim Döndürdüğü 50 satırlık İstanbul
fields=id,name,distance,sockets_summary Yalnızca adı geçen alanlar, adlandırıldıkları sırayla ~7 KB
fields=summary Yukarıdaki sade satır ~20 KB
fields=full (varsayılan) Zengin nesne, tüm soketler dahil ~118 KB

full veya summary olmayan her değer, virgülle ayrılmış seyrek liste olarak okunur. İzin verilen adlar:

id, station_epdk_id, epdk_id, name, slug, network, city, district, mahalle, address, longitude, latitude, phone, email, service_type, is_public, is_green_station, notes, station_status, yonga_url, error_message, sockets, sockets_summary, distance, created_at, updated_at.

Bilinmesi gereken üç kural:

  • Bir alanın şekli her zaman aynıdır. Her ad, fields=full karşılığına çözümlenir — fields=network iki anahtarlı özet nesneyi değil, yedi anahtarlı nesneyi döndürür — yani bir alanın değeri, yanında ne istediğinize bağlı değildir. full üzerine eklenen tek şey sockets_summary’dir; soket satırları olmadan soket sayılarını alabilmeniz için vardır.
  • Bilinmeyen bir ad 422 verir ve hata o adı açıkça söyler. Sessizce atmak, istediğiniz anahtarın eksik olduğu bir satır döndürürdü; bu da “yanlış yazdınız” değil “bu istasyonda böyle bir veri yok” gibi okunur. Boşluklar ve tekrarlar hoş görülür (id, name , id → id, name).
  • Seyrek seçim yanıtı kırpar, sorguyu değil. Aynı satırlar ve ilişkiler her hâlükârda yüklenir; yani bant genişliğinden ve ajan bağlamından tasarruf edersiniz, veritabanı süresinden değil.

Aynı fields davranışı, bu uç noktanın Form Request’ini paylaşan GET /charging-networks/{slug}/stations için de geçerlidir.

meta

"meta": {
  "pagination": { "page": 1, "limit": 1, "total_pages": 444, "total_results": 444 },
  "filters": { "longitude": 32.85, "latitude": 39.9387, "radius": 10, "search_term": null }
}

Toplulaştırma modu — group_by=network

Aynı filtreler için operatör başına tek bir { network: {id, name, slug}, station_count } satırı döndürür; station_count azalan sırada, meta.group_by, meta.total_groups, meta.total_results, meta.filters ile birlikte ve meta.pagination olmadan. “X’te hangi operatörler var” sorusunu tek çağrıda yanıtlar.

# Ankara'da ZES'in hızlı DC şarj cihazları
curl "https://dash.yonga.io/api/charging-stations?city=ankara&network=zes&socket_type=DC&power_min=50" \
  -H "Authorization: Bearer <token>"

# Bir koordinata en yakın 20 istasyon, sade satırlar
curl "https://dash.yonga.io/api/charging-stations?latitude=39,9387&longitude=32.85&radius=5&fields=summary&limit=20" \
  -H "Authorization: Bearer <token>"

# Bir liste satırını çizmeye yetecek kadarı — varsayılandan ~%90 daha küçük
curl "https://dash.yonga.io/api/charging-stations?city=istanbul&fields=id,name,distance,sockets_summary&limit=50" \
  -H "Authorization: Bearer <token>"

# Bilecik'te hangi operatörler var?
curl "https://dash.yonga.io/api/charging-stations?city=bilecik&group_by=network" \
  -H "Authorization: Bearer <token>"

# Yalnızca halka açık istasyonlar (3 Eylül 2026 öncesi varsayılanın döndürdüğü küme)
curl "https://dash.yonga.io/api/charging-stations?city=ankara&service_type=public" \
  -H "Authorization: Bearer <token>"

# Yalnızca özel hizmet veren (OZEL) filo ve depo istasyonları
curl "https://dash.yonga.io/api/charging-stations?city=ankara&service_type=private" \
  -H "Authorization: Bearer <token>"

GET /charging-stations/map — bir ilin tüm harita pinleri (sayfalamasız)

Sayfalı listeyi baştan sona taramak yerine tüm pinleri tek seferde isteyen harita görünümleri için.

Parametre Tip Açıklama
city string Zorunlu. İl slug’ı
network string İsteğe bağlı — pinleri tek operatöre daraltır

service_type=public ve station_status=active zorunludur, geçersiz kılınamaz — haritadaki bir iğne sürücüye söz verdiği için, il toplamları özel hizmet istasyonlarını saysa da bu akış onları dışarıda bırakır. Koordinatı boş olan satırlar atlanır.

{
  "data": [
    {
      "id": 5134, "slug": "baskoy-petrol", "name": "Başköy Petrol",
      "latitude": "40.09022900", "longitude": "30.01021100",
      "network": { "name": "zes", "slug": "zes" },
      "sockets_summary": { "total": 2, "ultra_fast": 0, "very_fast": 0, "fast": 0, "slow": 2 }
    }
  ],
  "meta": { "total": 29, "city": "bilecik" }
}

GET /charging-stations/slugs — yayınlanmış sayfa slug akışı (sayfalamasız)

Statik site üretimi ve site haritası için yol keşif akışı: genel detay sayfası olan her istasyon ve başka hiçbir şey. Tüm küme tek yanıtta döner; böylece bir build, 100 satırla sınırlı liste uç noktasını taramak yerine tek çağrı yapar.

Harita akışı gibi bu da yalnızca halka açık istasyonları döndürür (service_type=public, station_status=active; ikisi de geçersiz kılınamaz): dizine eklenen bir sayfa, sürücüye verilen kalıcı bir sözdür. Özel hizmet veren (OZEL) istasyonlar her toplamda sayılır ama ön-render edilmiş sayfa ve site haritası kaydı almaz.

Parametre Tip Varsayılan Açıklama
web_status string published published | draft | review — site haritasından bilinçli olarak dışlanan sayfaları listelemek için değiştirin
city string — Tek ile daralt
{
  "data": [
    {
      "slug": "ymy-ssangyong-sahsuvaroglu",
      "city_slug": "erzurum",
      "network_slug": "powersarj",
      "yonga_path": "sarj-istasyonlari/erzurum/ymy-ssangyong-sahsuvaroglu-powersarj",
      "yonga_url": "https://yonga.io/sarj-istasyonlari/erzurum/ymy-ssangyong-sahsuvaroglu-powersarj"
    }
  ],
  "meta": { "total": 278, "web_status": "published" }
}

yonga_path, host’a göreli sarj-istasyonlari/{city_slug}/{station_slug}-{network_slug} yoludur (istasyonun ağı yoksa -{network_slug} eki düşer); yonga_url ise bu yolun genel site köküyle (WEB_URL) öneklenmiş hali ve site haritasının duyurduğu kanonik URL’dir. İli olmayan istasyonlar atlanır — çözümlenebilir bir URL’leri yoktur.

GET /charging-stations/{slug} — istasyon detayı

Parametre Konum Açıklama
slug path Sayısal id, slug veya EPDK id (ör. ŞRJ/18971) — tek parametre, üç arama modu

Tam istasyon nesnesini coordinates {lat, lng}, google_place_id, web_status, notes ve tam sockets listesiyle (her soket ayrıca web_status taşır) döndürür. city nesnesi sade {id, name, slug, plaka} biçimindedir; district bir slug taşır. Eşleşme yoksa 404 hata zarfı.


5.4 Coğrafya (Bölge, İl, İlçe, Mahalle)

Türkiye’nin idari hiyerarşisi: bölge (7) → il (81) → ilçe (992) → mahalle (~49.000).

GET /regions — bölgeleri listele

Parametre Tip Varsayılan Açıklama
page int 1
limit int 25 Maks. 100 — tek çağrı 7 bölgenin tamamını döner
search string — Türkçe normalleştirilmiş ad filtresi
populate string — cities her bölgenin il listesini gömer

Yanıt — data[]: id, name, slug, cities_count, coordinates {lat,lng} (sınır kutusundan türetilir), bounds {northeast, southwest}, cities (populate=cities verilmedikçe null). Listede poligon dönmez.

populate=cities ile her satır kendi il listesini taşır — id, name, slug, plaka_id (başına sıfır eklenmiş, "06"), coordinates {lat,lng} — böylece plaka→bölge eşlemesinin tamamı yedi bölge detayı çağrısı yerine tek çağrıda gelir:

GET /api/regions?populate=cities

GET /regions/{slug} — bölge detayı

Parametre Konum Açıklama
slug path Bölge slug’ı (ör. marmara) veya sayısal id
populate query cities, polygon

Bölgedeki tüm iller üzerinden toplanan şarj toplamlarını ekler — total_stations, total_networks, total_ac_sockets, total_dc_sockets, total_power_kw — artı top_networks sıralaması (10 satır: {network: {id, name, slug}, station_count}). top_networks dahil hepsi, her iki hizmet şeklindeki faal istasyonları kapsar (§4). cities ve polygon, populate edilmedikçe null’dur.

GET /cities — illeri listele

Parametre Tip Varsayılan Açıklama
page int 1
limit int 25 Maks. 100 — limit=100 ile tek çağrıda 81 ilin tamamı döner
search string — Türkçe normalleştirilmiş ad filtresi
populate string — polygon — her ilin GeoJSON sınırını ekler (il başına ~50 KB; varsayılan olarak kapalı)

Yanıt — data[] öğesi

Alan Tip Notlar
id, tkgm_id, osm_relation_id int Tanımlayıcılar
plaka_id string Sıfır dolgulu plaka kodu, örn. Ankara "06"
name, slug string
coordinates object { lat, lng } merkez noktası
bounds object { northeast: {lat,lng}, southwest: {lat,lng} }
polygon object|null GeoJSON sınırı — populate=polygon verilmedikçe null

Liste hiçbir şarj toplamı taşımaz — toplamlar il detayındadır. Bu listenin kabul ettiği tek populate değeri polygon’dur.

GET /cities/{slug} — il detayı

Parametre Konum Açıklama
slug path İl slug’ı (ör. ankara), plaka_id, tkgm_id veya sayısal id
populate query districts, polygon

Liste alanlarına ek olarak total_stations, total_networks, total_ac_sockets, total_dc_sockets, total_power_kw (her iki hizmet şeklindeki faal istasyonları sayar — §4) ve top_networks (10 satır). districts ve polygon, populate edilmedikçe null’dur. Bilinmeyen tanımlayıcı için 404.

GET /cities/{citySlug}/districts — bir ilin ilçeleri

Parametre Tip Varsayılan Açıklama
citySlug path — İl slug’ı, plaka_id, tkgm_id veya id — bir il olmalıdır; ilçe slug’ı 404 döndürür
page int 1
limit int 50 Maks. 200
search string — İlçe adı filtresi
populate string — polygon

Yanıt — data[]: id, tkgm_id, name, slug, coordinates {lat,lng}, polygon. meta.city çözümlenen ili yansıtır (id, slug, name), ayrıca standart meta.pagination.

GET /cities/{citySlug}/districts/{districtSlug} — bir ilçenin mahalleleri

İlçe listesiyle aynı parametreler. Yanıt — data[]: id, mahalle_name, name, slug, tkgm_id, osm_relation_id, polygon; meta.city, meta.district, meta.pagination.

Mahalle ana verisi artık 992 ilçenin 958’ini kapsıyor (~49.000 satır). Kalan ~34 ilçede boş liste hâlâ mümkün — orada mahalle adlarını istasyon adreslerinden türetin.


5.5 Olaylar (Değişim Günlükleri)

Alt sistemlerdeki önbelleği senkron tutmak için kayan pencereler. İkisi de stats:read gerektirir.

GET /events/stations-changelog

Parametre Tip Varsayılan Açıklama
days int 30 Pencere uzunluğu; yanıtın her iki tarafına da uygulanır
{
  "data": {
    "added_stations":   [ { "id": 0, "station_epdk_id": "…", "name": "…", "slug": "…", "network_name": "…", "network_slug": "…", "created_at": "…", "updated_at": "…" } ],
    "removed_stations": [ { "id": 0, "station_epdk_id": "…", "name": "…", "slug": "…", "updated_at": "…", "created_at": "…" } ]
  },
  "meta": { "days": 30, "added_count": 12, "removed_count": 3 }
}

GET /events/networks-changelog

added_networks / removed_networks ile aynı yapı; her satır id, name, slug, company_name, type, created_at, updated_at (eklenen satırlar ayrıca network_status taşır).

Pasifleşme bir durum değil, bir olaydır. Bu uç noktalar pencere içinde pasifleşenleri bildirir, hâlihazırda pasif olan her şeyi değil. Zaman damgası updated_at’tir; bilinen sapmalar Docs/adr/0001-deactivation-is-an-event-windowed-by-updated-at.md içinde kayıtlıdır.


6. MCP Sunucusu

Yonga EV Charging Turkey (v1.0.0) — AI ajanları için aynı veriyi araçlar olarak sunan bir Model Context Protocol sunucusu. Laravel MCP ile oluşturulmuştur; araçlar dahili olarak REST denetleyicilerini çağırır, bu nedenle yanıtlar REST API ile aynı { data, meta } zarfını ve hata formatını kullanır.

6.1 Bağlantı

Taşıma Streamable HTTP
Uç nokta POST https://dash.yonga.io/mcp
Kimlik doğrulama Sanctum bearer token (Authorization: Bearer <token>), REST API ile aynı token — POST /api/login ile alınır. Sohbet uygulaması bağlayıcıları (Claude.ai, ChatGPT) bunun yerine OAuth ile giriş yapar — §6.2
Gerekli yetenekler stations:read, networks:read, map:read, stats:read yeteneklerinden herhangi biri — veya OAuth kapsamı mcp:use
Hesap izni access mcp (her kademe rolü bu izni taşır). Her çağrıda kontrol edilir; rol kaldırıldığında canlı token devre dışı kalır
Sorgu limiti /api/* ile aynı kademe limitleri (§4)

6.2 İstemci Yapılandırması

Claude Code (.mcp.json):

{
  "mcpServers": {
    "yonga-ev-charging-turkey": {
      "type": "http",
      "url": "https://dash.yonga.io/mcp",
      "headers": { "Authorization": "Bearer ${YONGA_MCP_TOKEN}" }
    }
  }
}

Claude Desktop / Cursor:

{
  "mcpServers": {
    "yonga-ev-charging-turkey": {
      "url": "https://dash.yonga.io/mcp",
      "headers": { "Authorization": "Bearer ${env:YONGA_MCP_TOKEN}" }
    }
  }
}

Claude.ai / ChatGPT — OAuth bağlayıcısı (kademeli açılıyor; her ortamda MCP_OAUTH_ENABLED ile etkinleştirilir)

Kopyalanacak token yok. https://dash.yonga.io/mcp adresini özel bağlayıcı olarak ekleyin — Claude.ai: Settings → Connectors → Add custom connector; ChatGPT: geliştirici modu bağlayıcısı — ardından açılan Yonga sayfasında giriş yapıp onaylayın. Hesaplar Yonga tarafından oluşturulur; kendi kendine kayıt yoktur.

Akış OAuth 2.1 yetkilendirme kodu + PKCE (S256); açık istemciler (token_endpoint_auth_method: none)
Keşif GET /.well-known/oauth-protected-resource/mcp (RFC 9728) → GET /.well-known/oauth-authorization-server (RFC 8414)
İstemci kaydı POST /oauth/register üzerinden dinamik (RFC 7591), IP başına saatte 10 ile sınırlı. Geri dönüş adresleri claude.ai, claude.com veya chatgpt.com üzerinde olmalıdır; diğerleri 400 invalid_redirect_uri döner
Yetkilendirme / token GET /oauth/authorize (/login üzerinden giriş, ardından onay ekranı) · POST /oauth/token
Kapsam mcp:use — tüm araçları kapsar. stations:read, networks:read, map:read, stats:read da istenebilir
Süreler Erişim token’ı 1 saat; yenileme token’ı 30 gün ve her kullanımda yenilenir — aktif bir bağlayıcı tekrar giriş istemez
Sorgu limiti Aynı hesabın Sanctum token’ı ile aynı kademe; ikisi tek bir kotayı paylaşır
İptal Yonga yöneticileri bir bağlantıyı iptal edebilir (yönetim paneli → Users → OAuth connections); uygulama bunun ardından yeniden giriş yapmak zorundadır

Geliştiriciler ve komut satırı araçları (Claude Code, Cursor, betikler) yukarıdaki gibi Sanctum token kullanmaya devam eder. localhost geri dönüşlü OAuth (Claude Code’un kendi akışı, Gemini CLI) etkin değildir.

6.3 Araçlar

Araç Amaç
list_charging_stations Filtrelerle istasyon araması; group_by=network ile operatör bazında toplulaştırma
get_station_info id / slug / EPDK id ile tek istasyon
find_nearby_stations Koordinat yakınındaki istasyonlar, en yakından uzağa
list_networks Ağ operatörlerini listele/ara
get_network_info id / slug ile tek ağ
geo Tek yol adresli araçla tüm coğrafya hiyerarşisi (il → ilçe → mahalle)

MCP yüzeyi REST API’den bilinçli olarak dardır: bölgeler, il harita pini akışı, yayınlanmış slug akışı, ağ fiyat/istasyon alt yolları ve değişim günlükleri yalnızca REST’tedir. Bunlar soru yanıtlama değil, toplu/build zamanı işleridir.


list_charging_stations

Türkiye genelinde EV şarj istasyonlarını ara. Sade satırlar (ad, koordinatlar, ağ/il/ilçe, soket sayıları) ve meta.pagination döndürür — kaç istasyonun eşleştiğini saymak için sayfalamak yerine meta.pagination.total_results değerini okuyun. Zengin istasyon nesnesi için fields=full, daha da kırpmak için seyrek liste, toplulaştırma için group_by=network kullanın.

Toplulaştırma modu. group_by=network, aynı filtreler için operatör başına tek bir { network, station_count } satırı döndürür; station_count azalan sırada, meta.group_by, meta.total_groups, meta.total_results ile birlikte ve meta.pagination olmadan. “X’te hangi operatörler var” sorusunu tek çağrıda böyle yanıtlarsınız.

Parametre Tip Açıklama
city string İl slug’ı, örn. istanbul, ankara
district string İlçe slug’ı, örn. kadikoy
network string Ağ operatörü slug’ı, örn. zes, esarj
connector_type string CCS2 | Type2 | CHAdeMO
socket_type string AC | DC
power_min / power_max number Soket güç aralığı kW cinsinden
service_type string public veya private; boş bırakılırsa ikisi birlikte (varsayılan). find_nearby_stations bunu yok sayar — her zaman yalnızca halka açık istasyonlar
is_green_station boolean Yalnızca yenilenebilir enerjili istasyonlar
station_status string active (varsayılan) | inactive
web_status string published | draft | review
data_status string Dahili veri hattı durumu
search_term string Ad, ağ, mahalle/ilçe/il, adres ve EPDK id üzerinde anahtar kelime araması — min. 3 karakter, aksan duyarsız, boşlukla ayrılan parçaların tümü eşleşmelidir
group_by string network — toplulaştırma modu (yukarıya bakın)
fields string summary (varsayılan) | full | virgülle ayrılmış seyrek liste, ör. id,name,city,sockets_summary — adlar ve kurallar §5.3 ile aynı
page integer Varsayılan 1
limit integer 1–100, varsayılan 20

MCP varsayılanları (fields=summary, limit=20), REST uç noktasının varsayılanlarından (full / 50) daha dardır — araç soru yanıtlamaya göre ayarlanmıştır, toplu veri çekmeye değil. İkisi de çağıran tarafından değiştirilebilir; veri seti çekimleri için REST API’yi kullanın.

full yerine seyrek listeyi tercih edin. 20 satırlık bir sayfada fields=full, summary’nin yaklaşık altı katı token demektir ve bunun neredeyse tamamı soket satırlarıdır. Bir veya iki ek alan gerekiyorsa — diyelim notes ya da yonga_url — onları adlandırın: fields=id,name,city,notes,yonga_url.

get_station_info

Tam soket listesiyle tek bir şarj istasyonunu getir.

Parametre Tip Açıklama
slug (zorunlu) string Sayısal id, slug veya station_epdk_id (ör. ŞRJ/18971)

Eşleşme yoksa 404 hata zarfı döndürür.

find_nearby_stations

Koordinat yakınındaki istasyonlar, en yakından uzağa sıralı (haversine). İnce satırlar döndürür: ad, koordinatlar, distance (km), ağ/il adları, soket sayıları. “Yakınımda / X noktası yakınında” için kullanın — il veya ağ genelinde listeler için list_charging_stations kullanın.

Parametre Tip Açıklama
latitude (zorunlu) number −90 … 90 (virgüllü ondalıklar 41,0082 kabul edilir)
longitude (zorunlu) number −180 … 180
radius number km, varsayılan 5, maks. 200
limit integer 1–100, varsayılan 50
fields string summary (varsayılan) | full | virgülle ayrılmış seyrek liste — adlar ve kurallar §5.3 ile aynı
city, network, connector_type, socket_type, is_green_station — list_charging_stations ile aynı anlam

service_type burada kabul edilmez ve geçersiz kılınamaz: “yakınımda”, sürücünün orada gerçekten şarj edebileceği sözünü verir; bu yüzden özel hizmet (OZEL) filo ve depo sahaları dışarıda kalır. Bu araçtaki tek zorunlu varsayılan odur — fields, radius ve limit sizin kontrolünüzdedir.

list_networks

Ağ operatörlerini (180+) listele/ara. Her satır şirket bilgileri, iletişim detayları, uygulama/web URL’leri ve fiyatlandırma (fiyat_ac, fiyat_dc_fast, fiyat_dc_ultra_fast) içerir. get_network_info öncesinde slug çözmek için idealdir.

Parametre Tip Açıklama
search_term string Ad, company_name ve slug üzerinde anahtar kelime araması (çift yönlü aksan duyarsız; sarj → ŞARJ)
network string Tam ağ slug’ı — emin değilseniz search_term kullanın
page / limit integer Varsayılan 1 / 25, maks. 100

MCP şeması, REST uç noktasından bilinçli olarak dardır; REST ayrıca type, hasPrices, web_status ve data_status kabul eder. Bunlar yönetim/veri hattı filtreleridir — HTTP üzerinden kullanmak için §5.2’ye bakın.

get_network_info

Tek bir ağ operatörü: şirket detayları, açıklama, iletişim bilgileri, URL’ler, fiyatlandırma.

Parametre Tip Açıklama
slug (zorunlu) string Sayısal id veya slug (ör. zes, esarj)

Yanıtın şekli sabittir — bu araç populate almaz.

geo

Tek yol adresli araçla tüm idari hiyerarşide gezinin. path, dosya sistemi yolu gibi eğik çizgiyle ayrılmış yer tanımlayıcıları zinciridir (slug, plaka_id, tkgm_id veya sayısal id):

Çağrı Döndürür
geo() (path yok) 81 ilin tamamı, sayfalanmış (varsayılan limit=100 ⇒ tek çağrı)
geo(path="ankara") İl detayı: koordinatlar, şarj toplamları (total_stations, total_networks, AC/DC soketler, total_power_kw — her iki hizmet şeklindeki faal istasyonlar) ve top_networks sıralaması
geo(path="ankara", include="children") İlin ilçeleri, sayfalanmış
geo(path="ankara/cankaya") İlçenin mahalleleri, sayfalanmış
geo(path="ankara/cankaya/kizilay") Tek bir mahallenin detayı
Parametre Tip Açıklama
path string Eğik çizgiyle ayrılmış tanımlayıcı zinciri; "" illeri listeler
include string children — adreslenen düğümün bir altındaki seviyeyi listeler. Uygulanmadığı yerde yok sayılır
geometry string none (varsayılan) | bbox ([west,south,east,north]) | centroid ([lng,lat]) | full (ham GeoJSON — büyük olabilir)
search string Listelerde Türkçe normalleştirilmiş ad filtresi (maks. 100 karakter)
page integer Varsayılan 1
limit integer İller maks. 100; ilçeler/mahalleler maks. 200; varsayılan 100

Her yanıt meta.level, çözümlenen ataların breadcrumb değerini ve bir sonraki çağrı için kanonik slug’ları taşır — bir yerin seviyesini önceden bilmeniz gerekmez. meta.pagination, has_more ve next_page ile genişletilmiştir. Bilinmeyen path segmentleri 404 hata zarfı döndürür.

include="stats" artık yok: top_networks her il detayıyla birlikte geliyor. Bölgeler geo üzerinden adreslenemez — REST’te GET /api/regions kullanın.

6.4 Kullanım Rehberi ve Dikkat Edilecekler

  • Varsayılan filtreler: list_charging_stations her iki hizmet şeklindeki aktif istasyonları döndürür ve geo il/bölge toplamları aynı filtreyi uygular — bir il için meta.pagination.total_results o ilin total_stations değeriyle eşleşir. Fark açıklamak yerine tek sayı bildirin. find_nearby_stations istisnadır: her zaman yalnızca halka açık istasyonları döndürür, dolayısıyla bir bölge için verdiği sayı o bölgenin toplamından düşük olabilir; bu da bir tutarsızlık değildir.
  • Slug’lar Türkçe normalleştirilmiştir. 404 durumunda tahmin etmek yerine list_networks veya geo ile tam slug’ı çözün (ör. doğru slug neva-sarj, nova-sarj değil).
  • search_term 3 karakter ister, aksanları çift yönlü katlar; boşlukla ayrılan parçaların tümü eşleşmelidir — "ankara zes" sonucu genişletmez, daraltır.
  • “Kaç tane” ve “hangi operatörler” sorularını tek toplulaştırma çağrısıyla yanıtlayın, asla sayfalayarak değil. list_charging_stations(city=…, group_by="network") bölgedeki her operatörü station_count ile döndürür ve normal aramayla aynı filtreleri kabul eder — böylece “Kadıköy’de hangi ağların DC şarjı var” sorusunu da yanıtlar (district="kadikoy", socket_type="DC", group_by="network"). Yalnızca eşleşme sayısı için meta.pagination.total_results zaten yeterlidir. geo(path=il).top_networks ise 10 ile sınırlı bir kolaylık sıralaması olarak kalır.
  • Kullanacağınız alanları isteyin. summary, soket satırlarını değil soket sayılarını (sockets_summary) taşır — “ne kadar hızlı” sorusuna yeter. fields=full’a yalnızca tüm kayda ihtiyacınız olduğunda uzanın; bir iki ek alan söz konusuysa seyrek liste (fields=id,name,notes) bağlamın çok küçük bir kısmına mal olur.
  • Sayfalama, kullanıcıya daha fazla sonuç göstermek içindir; veri seti toplamak için değil. Filtreleri daraltmayı veya group_by’a geçmeyi tercih edin; toplu veri çekimi REST API’ye aittir.
  • Hiyerarşi önemlidir: il > ilçe > mahalle. Bir ilçe il değildir — ancak geo bunu yol ile adresler (ankara/cankaya), bu nedenle nadiren sorun olur.
  • Mahalle verisi artık büyük ölçüde tamamlandı (992 ilçenin 958’i). Bir ilçe hâlâ total: 0 döndürürse mahalle adlarını list_charging_stations ile istasyon adreslerinden türetin.
  • geometry değeri null none istendiğinde (varsayılan) veya sınır verisi henüz içe aktarılmadığında — beklenen davranış, hata değil.

6.5 Örnek İstemler

Kullanıcının sorduğu soru ve bunun dönüşmesi gereken araç çağrısı.

İstasyon bulma

İstem Çağrı
“Kadıköy’de şarj istasyonu var mı?” list_charging_stations(district="kadikoy")
“Bana en yakın şarj istasyonları nerede?” find_nearby_stations(latitude=…, longitude=…) — koordinat gerekir; verilmediyse sorun
“Beşiktaş’ta 2 km içinde DC hızlı şarj var mı?” find_nearby_stations(latitude=…, longitude=…, radius=2, socket_type="DC")
“Ankara’da 150 kW üstü CCS2 istasyonları listele” list_charging_stations(city="ankara", connector_type="CCS2", power_min=150)
“Migros AVM şarj istasyonunun detayları” list_charging_stations(search_term="Migros") → eşleşen kayıt için get_station_info(slug=…)
“Yeşil enerjiyle çalışan istasyonlar hangileri?” list_charging_stations(is_green_station=true)

Sayma ve karşılaştırma

İstem Çağrı
“İzmir’de hangi operatörler var?” list_charging_stations(city="izmir", group_by="network") — sayfalayarak değil
“Ankara’da kaç şarj istasyonu var?” list_charging_stations(city="ankara") → meta.pagination.total_results
“Çankaya’da DC şarjı olan ağlar hangileri?” list_charging_stations(district="cankaya", socket_type="DC", group_by="network")
“İstanbul’da en çok istasyonu olan 3 operatör” list_charging_stations(city="istanbul", group_by="network") → ilk 3 satır
“ZES’in Bursa’da kaç istasyonu var?” list_charging_stations(city="bursa", network="zes") → meta.pagination.total_results

Ağlar ve fiyatlandırma

İstem Çağrı
“Türkiye’deki şarj ağlarını listele” list_networks()
“Trugo’nun fiyatları ne kadar?” Slug’ı çözmek için list_networks(search_term="trugo") → get_network_info(slug="trugo")
“Fiyatı belli olan ağları karşılaştır” list_networks() → fiyat_ac / fiyat_dc_fast / fiyat_dc_ultra_fast karşılaştırın (hasPrices filtresi yalnızca REST’te)

Coğrafya

İstem Çağrı
“Türkiye’nin illerini listele” geo() — 81 il tek çağrıda
“Ankara’nın ilçeleri neler?” geo(path="ankara", include="children")
“Ankara’nın şarj istatistikleri” geo(path="ankara") — toplamlar ve top_networks il detayıyla gelir
“Kadıköy hangi ilde?” geo(path="istanbul/kadikoy") → breadcrumb okuyun
“İzmir’in sınırlarını harita için ver” geo(path="izmir", geometry="full")

Geri soru gerektiren istemler

İstem Neden Yapılacak
“Yakınımdaki istasyonlar” İstemde koordinat yok Konum isteyin veya il alıp list_charging_stations(city=…) ile ilerleyin
“Tüm istasyonları ver” 16.000+ satır — soru değil, veri seti çekimi REST API’yi önerin (§5.3) veya il/ilçeye daraltın
“Marmara bölgesindeki istasyonlar” geo bölge seviyesini adreslemez REST’te GET /api/regions/marmara kullanın ya da bölgenin illerini listeleyip sorgulayın
“Nova Şarj’ın istasyonları” Slug tahmini; doğrusu neva-sarj Önce list_networks(search_term="nova"), sonra çözülen slug ile filtreleyin

7. Hata Referansı

Veri uç noktaları tutarlı bir hata zarfı döndürür:

{
  "data": null,
  "error": {
    "status": 404,
    "name": "NotFoundError",
    "message": "Charging station not found",
    "details": { "slug": "no-such-station" }
  }
}
Durum error.name Anlam Tipik neden
401 — Kimlik doğrulanmamış Eksik, iptal edilmiş veya süresi dolmuş bearer token. /mcp üzerinde yanıt bir WWW-Authenticate başlığı taşır (§6.1)
403 ForbiddenError Eksik yetenek Token, yol grubunun gerektirdiği yeteneği taşımıyor (ör. /events/* için stats:read); /mcp üzerinde ayrıca access mcp izni olmayan bir hesap
404 NotFoundError Bulunamadı Bilinmeyen slug / id / EPDK id, bilinmeyen il veya ilçe
422 ValidationError Doğrulama hatası Parametre doğrulamadan geçemedi (limit > 100, search_term 3 karakterden kısa, geçersiz enum); hatalı giriş bilgileri de
429 TooManyRequestsError Limit aşıldı Kademe kotası veya ani yük tavanı aşıldı — Retry-After ile geri çekilin
500 InternalServerError Sunucu hatası Beklenmeyen hata (detaylar sunucuda loglanır, asla döndürülmez) — yeniden deneyin, ardından bildirin

İki yanıt zarfı bilinçli olarak kırar:

// 401 — geçerli token yok
{ "meta": { "message": "Valid Access token is Required", "status": 401 } }

// 404 — bilinmeyen API yolu (geri dönüş)
{ "message": "API endpoint not found", "status": 404 }

422, alan bazlı mesajları error.details içine koyar ve bu mesajlar isteğin diline göre gelir:

{
  "data": null,
  "error": {
    "status": 422,
    "name": "ValidationError",
    "message": "The given data was invalid.",
    "details": { "limit": ["limit tamsayı olmalıdır."] }
  }
}

/docs/api.json (Scramble OpenAPI dışa aktarımı, API v1.1.5), laravel-app/routes/api.php, laravel-app/routes/ai.php, App\Http\Controllers\Api denetleyicileri ve laravel-app/app/Mcp/ içindeki MCP sunucu uygulamasından üretilmiştir. Rakamlar 2026-08-30 tarihinde canlı veri setine karşı doğrulanmıştır. MCP kimlik doğrulaması (§3, §6.1, §6.2) 12 Ekim 2026’da routes/ai.php, config/mcp.php ve Docs/62 kaynaklarından güncellenmiş ve özellik testleriyle kapsanmıştır — henüz canlı bir sunucuya karşı denenmemiştir.