Bu doküman, Tatvan Belediyesi kurumsal web sitesinin ALO 153 Destek Merkezi ile entegrasyonu için hazırlanmıştır. Vatandaş; yeni talep oluşturur, kendi talebini sorgular, aşamasını görür, iletişim bilgilerini düzeltir, yanıt yazar, çözüldü olarak işaretler veya kaydını kapatır.
| Base URL | https://153.vegabyte.com.tr/api/web/v1 |
| Biçim | JSON (istek ve yanıt) |
| Kimlik doğrulama | X-API-Key başlığı |
| Karakter kodlaması | UTF-8 |
| Çevrimiçi sürüm | https://153.vegabyte.com.tr/api-dokumantasyon |
Bu dokümanın her zaman güncel hâli yukarıdaki adreste yayımlanır; giriş gerektirmez. Elinizdeki kopya eskimiş olabilir, kuşkuya düştüğünüzde çevrimiçi sürümü esas alın.
1. Kimlik Doğrulama
Her istek (yalnızca /health hariç) geçerli bir API anahtarı gerektirir.
Anahtar, yönetim panelinden Yönetim → API Anahtarları ekranından üretilir.
X-API-Key: tvb_xxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
Kritik güvenlik kuralları
- Anahtar yalnızca sunucu tarafında saklanmalıdır. Tarayıcıya inen JavaScript'e, mobil pakete veya herkese açık depoya konulmamalıdır. Web sitesi, tarayıcıdan gelen isteği kendi sunucusunda karşılayıp API'ye sunucu-sunucu (server-to-server) iletmelidir.
- Anahtar yalnızca üretildiği anda bir kez gösterilir; sistemde geri çevrilemez biçimde (özet olarak) saklanır. Kaybedilirse yenisi üretilir.
- Anahtar sızarsa panelden anında devre dışı bırakılabilir.
- Anahtar URL'de (query string) gönderilmemelidir; yalnızca başlıkta.
Hata yanıtları (kimlik doğrulama)
| Durum | Anlamı |
|---|---|
401 |
Anahtar eksik veya geçersiz |
403 |
Anahtar devre dışı bırakılmış |
2. Hız Sınırları (Rate Limit)
| Uç grubu | Sınır |
|---|---|
Yeni talep (POST /tickets) |
Ziyaretçi başına dakikada 3 istek |
Sorgulama (lookup, tickets/{token}, neighborhoods) |
Ziyaretçi başına dakikada 30 istek |
İşlem (update, reply, resolve, close) |
Ziyaretçi başına dakikada 10 istek |
| Başarısız eşleşme (yanlış talep no/telefon) | Ziyaretçi başına 10 başarısız denemeden sonra 5 dk kilit |
Sınır aşıldığında 429 Too Many Requests döner. Web sitesi bu durumu
kullanıcıya "Çok fazla deneme yaptınız, lütfen biraz sonra tekrar deneyin"
şeklinde göstermelidir.
2.1 X-Client-IP — ziyaretçiyi bildirin (önemli)
İstekler web sitesinin sunucusundan geldiği için, API tüm ziyaretçileri varsayılan olarak tek bir IP gibi görür. Bu durumda bir kişinin denemeleri sitenin tüm ziyaretçilerini kilitler.
Bunu önlemek için her istekte son kullanıcının IP adresini iletin:
X-Client-IP: 88.240.15.72
Sınırlar o ziyaretçiye özel uygulanır; bir ziyaretçinin kilitlenmesi diğerlerini etkilemez. Başlık gönderilmezse tüm trafik ortak kotayı paylaşır.
Bu başlık yalnızca anahtar sahibi güvenilen istemciden kabul edilir. Değeri son kullanıcının gerçek IP'si olmalıdır (
$_SERVER['REMOTE_ADDR']veya proxy arkasındaysanız doğruladığınızX-Forwarded-Fordeğeri).
3. Sahiplik Doğrulaması
Vatandaşın yalnızca kendi talebine erişebilmesi için her istek sahiplik kanıtı taşır. İki yöntemden biri kullanılır:
- Takip token'ı —
track_token: talep oluşturulurken üretilen, tahmin edilemez benzersiz değer (vatandaşa SMS/e-posta ile giden takip bağlantısında yer alır). - Talep numarası + telefon —
ticket_number+phone: ikisi birlikte eşleşmelidir.
Kanıt eşleşmezse 404 döner; talebin var olup olmadığı dahi sızdırılmaz.
Not: Telefon numarası içeren tüm sorgular
POSTile yapılır. Numara URL'de taşınsaydı sunucu/proxy erişim loglarına düşerdi (KVKK riski).
Yalnızca telefonla sorgulama yoktur. Telefon numarası gizli bir bilgi değildir; tek başına yeterli sayılsaydı numarayı bilen herkes o kişinin tüm taleplerini, adresini ve yazışmalarını görebilirdi. Bu nedenle sorgulama daima talep numarası + telefon ya da takip token'ı ile yapılır.
4. Uçlar (Endpoints)
4.1 Servis Durumu
GET /health
Anahtar gerektirmez. İzleme (uptime) kontrolü için kullanılır.
{
"status": "ok",
"service": "tatvan-web-api",
"time": "2026-07-29T21:21:14+03:00"
}
4.2 Mahalle Listesi (form için)
GET /neighborhoods
X-API-Key: ...
Talep formundaki mahalle açılır listesini doldurmak içindir. Yalnızca aktif ve herkese açık mahalleler döner; çağrı merkezine özel kayıtlar (örn. "Adres Belirtilmedi") dışarı verilmez.
Yanıt: 200 OK
{
"data": [
{ "id": 1, "name": "Atatürk Mahallesi" },
{ "id": 2, "name": "Sahil Mahallesi" }
]
}
Liste nadiren değişir; sitenizde günlük önbelleğe almanız önerilir.
4.3 Yeni Talep Oluşturma
POST /tickets
X-API-Key: ...
X-Client-IP: 88.240.15.72
Content-Type: application/json
{
"citizen_name": "Ahmet Yılmaz",
"citizen_phone": "0532 999 88 77",
"citizen_email": "ahmet@example.com",
"neighborhood_id": 2,
"address": "Sahil Mah. 123. Sok. No:4",
"subject": "Sokak lambası yanmıyor",
"description": "Sokağımızdaki aydınlatma direği üç gündür yanmıyor.",
"latitude": 38.5012,
"longitude": 42.2795,
"kvkk_consent": true
}
| Alan | Zorunlu | Kural |
|---|---|---|
citizen_name |
✔ | 3–120 karakter |
citizen_phone |
✔ | 10–20 karakter; esnek biçim kabul edilir |
citizen_email |
— | Geçerli e-posta, en fazla 150 karakter |
neighborhood_id |
— | GET /neighborhoods listesinden bir kimlik |
address |
— | En fazla 255 karakter |
subject |
✔ | 5–160 karakter |
description |
✔ | 10–4000 karakter |
latitude / longitude |
— | Sayısal koordinat |
kvkk_consent |
✔ | true olmalıdır |
photos[] |
— | En fazla 5 dosya, her biri en fazla 8 MB |
Kategori (konu başlığı) gönderilmez. Talebi hangi kategoriye ve müdürlüğe yönlendireceğine çağrı merkezi temsilcisi karar verir. Vatandaş yalnızca konuyu serbest metin olarak yazar.
Fotoğraf/belge eki ile gönderim
Ek göndereceksiniz multipart/form-data kullanın (JSON yerine). İzin verilen
türler: jpg, jpeg, png, webp, heic, pdf, doc, docx.
curl -X POST https://153.vegabyte.com.tr/api/web/v1/tickets \
-H "X-API-Key: $ALO153_API_KEY" \
-H "X-Client-IP: 88.240.15.72" \
-F "citizen_name=Ahmet Yılmaz" \
-F "citizen_phone=05329998877" \
-F "subject=Sokak lambası yanmıyor" \
-F "description=Aydınlatma direği üç gündür yanmıyor." \
-F "kvkk_consent=1" \
-F "photos[]=@lamba.jpg" \
-F "photos[]=@sokak.jpg"
Yanıt: 201 Created — Talep Detay Nesnesi
Yanıttaki ticket_number ve track_token değerlerini kullanıcıya gösterin;
track_token takip ekranına yönlendirme için kullanılır. Vatandaşa ayrıca
sistem tarafından bilgilendirme SMS'i/e-postası gönderilir.
Hatalar:
| Durum | Anlamı |
|---|---|
422 |
Doğrulama hatası (eksik alan, KVKK onayı yok, geçersiz dosya türü/boyutu) |
429 |
Dakikada 3 talep sınırı aşıldı |
4.4 Takip Token'ı ile Talep Detayı
GET /tickets/{track_token}
X-API-Key: ...
Vatandaşa gönderilen takip bağlantısındaki token ile talebin tüm detayını döner.
Yanıt: 200 OK — bkz. Talep Detay Nesnesi
Hatalar: 404 (talep bulunamadı)
4.5 Talep No + Telefon ile Sorgulama
POST /tickets/lookup
X-API-Key: ...
Content-Type: application/json
{
"ticket_number": "153-2026-000004",
"phone": "0532 999 88 77"
}
Telefon numarası esnek biçimde kabul edilir: 05329998877, 0532 999 88 77,
+90 532 999 88 77, 905329998877 — hepsi aynı numaraya normalize edilir.
Yanıt: 200 OK — Talep Detay Nesnesi
Hatalar:
| Durum | Anlamı |
|---|---|
404 |
Talep numarası ve telefon eşleşmedi |
422 |
Geçersiz telefon formatı |
429 |
Çok fazla başarısız deneme |
4.6 Bilgi Düzeltme (Düzenleme)
POST /tickets/update
X-API-Key: ...
Content-Type: application/json
{
"track_token": "5b7d4c7e-...",
"citizen_name": "Ahmet Yılmaz",
"citizen_email": "yeni@example.com",
"address": "Sahil Mah. 123. Sok. No:6",
"neighborhood_id": 3
}
Vatandaşın, talebini oluştururken hatalı/eksik girdiği iletişim ve konum
bilgilerini düzeltmesi içindir. Sahiplik kanıtı olarak track_token yerine
ticket_number + phone de gönderilebilir.
Değiştirilebilen alanlar
| Alan | Kural |
|---|---|
citizen_name |
3–120 karakter |
citizen_email |
Geçerli e-posta veya null |
address |
En fazla 255 karakter veya null |
neighborhood_id |
GET /neighborhoods listesinden bir kimlik veya null |
Yalnızca gönderdiğiniz alanlar değerlendirilir (kısmi güncelleme); göndermediğiniz alanlar olduğu gibi kalır.
Değiştirilemeyen alanlar
- Telefon numarası — sahiplik kanıtıdır; değiştirilmesi talebin başkasına devredilmesi anlamına gelirdi. İstekte gönderilse bile yok sayılır.
- Konu ve açıklama — personelin üzerinde çalıştığı içeriktir. Ek bilgi için yanıt yazma ucunu kullanın.
Süre kısıtı
Düzeltme yalnızca talep oluşturulduktan sonraki ilk 24 saat içinde ve talep
açıkken yapılabilir. Süre dolduktan sonra 409 döner; bu durumda vatandaş
yanıt yazarak düzeltmeyi iletebilir.
Yanıt: 200 OK
{
"message": "Bilgileriniz güncellendi.",
"updated": [
"Ad Soyad: \"Ahmet Yilmaz\" → \"Ahmet Yılmaz\"",
"Adres: \"Sahil Mah. 123. Sok. No:4\" → \"Sahil Mah. 123. Sok. No:6\""
],
"data": { }
}
updated dizisi uygulanan değişikliklerin okunabilir özetidir; kullanıcıya
onay mesajı olarak gösterilebilir. Aynı değişiklik panelde personele iç not
olarak da işlenir, böylece kayıt geçmişi izlenebilir kalır.
Hatalar:
| Durum | Anlamı |
|---|---|
409 |
24 saatlik düzeltme süresi doldu veya talep kapatılmış |
422 |
Doğrulama hatası ya da hiçbir alanda değişiklik yok |
404 |
Sahiplik eşleşmedi |
4.7 Talebe Yanıt Yazma
POST /tickets/reply
X-API-Key: ...
Content-Type: application/json
{
"track_token": "5b7d4c7e-...",
"message": "Sorun devam ediyor, tekrar bakılabilir mi?"
}
Sahiplik kanıtı olarak track_token yerine ticket_number + phone de
gönderilebilir. message: 2–1000 karakter.
Yanıt: 201 Created
{
"message": "Yanıtınız talebinize eklendi.",
"data": {
"id": 12,
"body": "Sorun devam ediyor, tekrar bakılabilir mi?",
"author_type": "citizen",
"created_at": "2026-07-29T21:22:07+03:00"
}
}
Hatalar: 409 (talep kapalı), 404, 422
4.8 Çözüldü Olarak İşaretleme
POST /tickets/resolve
X-API-Key: ...
Content-Type: application/json
{
"track_token": "5b7d4c7e-...",
"note": "Sorun giderildi, teşekkürler."
}
note isteğe bağlıdır (en fazla 1000 karakter).
Yanıt: 200 OK
{
"message": "Talebiniz çözüldü olarak işaretlendi.",
"data": {
"ticket_number": "153-2026-000004",
"status": { "value": "resolved", "label": "Çözüldü", "order": 3, "color": "teal" },
"resolved_at": "2026-07-29T21:23:07+03:00"
}
}
Hatalar: 409 (zaten çözülmüş), 404
4.9 Kaydı Kapatma
POST /tickets/close
X-API-Key: ...
Content-Type: application/json
{
"track_token": "5b7d4c7e-...",
"reason": "Talebimden vazgeçtim."
}
Vatandaşın talebinden vazgeçmesi / kaydı sonlandırması içindir.
reason isteğe bağlıdır (en fazla 500 karakter).
Önemli: Kayıt silinmez. Yönetim panelinde ve raporlarda görünmeye devam eder; yalnızca "Çözüldü" durumuna alınır ve geçmişine "Vatandaş kaydı kapattı" notu işlenir. Kurumsal arşiv bütünlüğü korunur.
Yanıt: 200 OK
{
"message": "Kaydınız kapatıldı. Kurum arşivinde saklanmaya devam eder.",
"data": {
"ticket_number": "153-2026-000004",
"status": { "value": "resolved", "label": "Çözüldü", "order": 3, "color": "teal" },
"closed_at": "2026-07-29T21:23:07+03:00"
}
}
Hatalar: 409 (zaten kapalı), 404
5. Talep Detay Nesnesi
{
"data": {
"ticket_number": "153-2026-000004",
"track_token": "5b7d4c7e-...",
"subject": "API test talebi",
"status": { "value": "resolved", "label": "Çözüldü", "order": 3, "color": "teal" },
"is_open": false,
"category": "Alt Yapı / Yol Şikayeti",
"neighborhood": "Sahil Mahallesi",
"department": "Fen İşleri Müdürlüğü",
"is_emergency": false,
"created_at": "2026-07-29T21:22:40+03:00",
"resolved_at": "2026-07-29T21:23:07+03:00",
"description": "Talep açıklaması...",
"citizen": {
"name": "Test Vatandaş",
"phone": "05329998877",
"email": null,
"address": "Test Adres"
},
"location": { "latitude": null, "longitude": null },
"attachments_count": 0,
"stages": [
{ "key": "received", "label": "Talep Alındı", "order": 0, "state": "completed", "completed": true, "active": false, "reached_at": "2026-07-29T21:22:40+03:00" },
{ "key": "forwarded", "label": "Birime İletildi", "order": 1, "state": "completed", "completed": true, "active": false, "reached_at": null },
{ "key": "in_review", "label": "İnceleniyor", "order": 2, "state": "completed", "completed": true, "active": false, "reached_at": null },
{ "key": "resolved", "label": "Çözüldü", "order": 3, "state": "completed", "completed": true, "active": false, "reached_at": "2026-07-29T21:23:07+03:00" }
],
"replies": [
{
"id": 4,
"body": "Talebiniz ilgili müdürlüğe iletilmiştir.",
"author_type": "staff",
"author_name": "Merve K.",
"created_at": "2026-07-29T21:23:31+03:00"
}
],
"can": { "reply": false, "resolve": false, "close": false }
}
}
Alan açıklamaları
| Alan | Açıklama |
|---|---|
status.value |
received, forwarded, in_review, resolved |
status.order |
0–3 arası sıra numarası |
status.color |
Öneri renk anahtarı: sky, blue, amber, teal |
is_open |
Talep hâlâ açık mı |
citizen |
Vatandaşın kendi bilgileri (tam) |
replies[].author_type |
citizen (vatandaş) veya staff (belediye personeli) |
replies[].author_name |
Personel için soyadı maskeli (örn. Merve K.); vatandaş yanıtlarında null |
attachments_count |
Talebe eklenen dosya sayısı (yalnızca sayı) |
can |
Bu talepte hangi işlemlerin yapılabileceği — butonları buna göre gösterin |
Ek dosyalar indirilemez.
attachments_countyalnızca kaç dosya eklendiğini bildirir; dosyaların kendisi web API'si üzerinden sunulmaz. Vatandaşın yüklediği belgeler yalnızca yetkili personelin panelinde görüntülenir. Sitenizde "3 dosya eklediniz" biçiminde bilgi gösterebilirsiniz.
Aşama (stage) durumları
state |
Anlamı | Önerilen gösterim |
|---|---|---|
completed |
Bu aşama tamamlandı | Dolu / işaretli |
active |
Talep şu an bu aşamada | Vurgulu / animasyonlu |
pending |
Henüz ulaşılmadı | Soluk |
reached_at alanı, aşamaya ulaşıldığı an (ISO 8601). null ise o aşama için
ayrı bir kayıt tutulmamıştır (örn. doğrudan çözüme geçen talepler).
Gizlilik notları
- Belediye personelinin soyadı maskelenir (
Merve K.); tam ad dışarı verilmez. - Personelin iç notları (dahili yazışmalar) API'de hiçbir koşulda dönmez.
- Vatandaşın kendi ad/telefon/adres bilgisi tam döner (kendi kaydını sorgulamaktadır).
6. Hata Biçimi
Doğrulama hataları Laravel standardındadır:
{
"message": "Geçerli bir cep telefonu numarası giriniz (örn. 0532 111 22 33).",
"errors": {
"phone": ["Geçerli bir cep telefonu numarası giriniz (örn. 0532 111 22 33)."]
}
}
Diğer hatalarda yalnızca message döner.
| Kod | Anlamı |
|---|---|
200 |
Başarılı |
201 |
Oluşturuldu (yeni talep, yanıt ekleme) |
401 |
API anahtarı eksik/geçersiz |
403 |
API anahtarı devre dışı |
404 |
Talep bulunamadı veya sahiplik eşleşmedi |
409 |
İşlem talebin mevcut durumuyla çelişiyor (örn. kapalı talebe yanıt) |
422 |
Doğrulama hatası (eksik/geçersiz alan) |
429 |
Hız sınırı aşıldı |
7. Örnek Entegrasyon
PHP (sunucu tarafı)
$response = Http::withHeaders([
'X-API-Key' => env('ALO153_API_KEY'),
'Accept' => 'application/json',
])
->post('https://153.vegabyte.com.tr/api/web/v1/tickets/lookup', [
'ticket_number' => $request->input('ticket_number'),
'phone' => $request->input('phone'),
]);
if ($response->status() === 404) {
return back()->withErrors('Talep numarası ve telefon eşleşmedi.');
}
$ticket = $response->json('data');
Node.js (sunucu tarafı)
const res = await fetch('https://153.vegabyte.com.tr/api/web/v1/tickets/lookup', {
method: 'POST',
headers: {
'X-API-Key': process.env.ALO153_API_KEY,
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({ ticket_number: ticketNumber, phone }),
});
if (res.status === 404) throw new Error('Talep bulunamadı.');
const { data } = await res.json();
cURL
curl -X POST https://153.vegabyte.com.tr/api/web/v1/tickets/lookup \
-H "X-API-Key: $ALO153_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ticket_number":"153-2026-000004","phone":"05329998877"}'
8. Web Sitesi İçin Öneriler
- Anahtarı gizleyin. Tarayıcıdan gelen formu kendi sunucunuzda karşılayın, API'ye oradan gidin. Anahtar hiçbir zaman istemciye inmemelidir.
X-Client-IPgönderin. Aksi halde tüm ziyaretçileriniz aynı hız sınırı kotasını paylaşır ve bir kişi hepsini kilitleyebilir (bkz. bölüm 2.1).- Formda kendi bot korumanızı kullanın. Yeni talep ucu dakikada 3 istekle sınırlıdır; buna ek olarak sitenizde captcha/honeypot bulundurun.
- Mahalle listesini önbelleğe alın.
GET /neighborhoodsgünde bir kez çekilmesi yeterlidir. - Aşama çubuğunu
stagesdizisiyle çizin.statealanı doğrudan tamamlandı/aktif/bekliyor gösterimine karşılık gelir. - Butonları
cannesnesine göre gösterin. Kapalı taleplerde yanıt/çözüldü/kapat butonları gizlenmelidir; aksi halde409alırsınız. - Düzenleme butonunu süreye göre gösterin.
created_atüzerinden 24 saat geçmişse "Bilgilerimi düzelt" seçeneğini gizleyin. - KVKK uyarısı gösterin. Hem talep formunda hem sorgulama ekranında kişisel veri işlendiğine dair bilgilendirme ve açık onay kutusu bulunmalıdır.
- Sorgulama formunda iki alanı da isteyin. Yalnızca telefonla sorgulama bilinçli olarak desteklenmez (bkz. bölüm 3). Formunuzda hem talep numarası hem telefon alanı zorunlu olmalıdır.
- Takip bağlantısını kullanıcıya hatırlatın. Talep oluşturulduğunda dönen
track_tokenile hazırlanan bağlantı, kullanıcının talep numarasını hatırlamadan doğrudan takip ekranına girmesini sağlar.
9. Çalışan Örnek Entegrasyon
Bu dokümandaki tüm uçları kullanan, çalışır durumda bir referans uygulama hazırlanmıştır. Kendi entegrasyonunuzu yazmadan önce incelemeniz önerilir.
| Adres | https://153.vegabyte.com.tr/ornek/ |
| Erişim parolası | Sistem yöneticisinden talep edilir |
Örnek uygulama düz PHP ile yazılmıştır ve şunları gösterir:
- Anahtarın sunucu tarafında tutulması ve isteklerin sunucu-sunucu iletilmesi
(
lib/Alo153Client.php) X-Client-IPbaşlığının doğru gönderimi- Fotoğraf ekli talep oluşturma (
multipart/form-data) - Talep numarası + telefon ile sorgulama ve takip token'ı ile detay
- Aşama çubuğunun
stagesdizisiyle çizilmesi - Yanıt yazma, bilgi düzeltme, çözüldü işaretleme ve kayıt kapatma
- Her ekranda yapılan API çağrısının istek/yanıt/süre dökümü (teknik günlük)
Örnek site canlı API'ye bağlıdır; burada oluşturduğunuz talepler gerçek kayıt olarak sisteme düşer ve vatandaşa SMS gider. Test ederken bunu göz önünde bulundurun.
10. Sürüm ve Destek
- Sürüm: v1 (
/api/web/v1) - Geriye dönük uyumsuz değişiklikler yeni sürüm yolu (
/api/web/v2) ile yayınlanır. - Yeni anahtar talebi, anahtar iptali ve teknik destek: yönetim paneli Yönetim → API Anahtarları ekranı / sistem yöneticisi.
Değişiklik geçmişi
| Tarih | Değişiklik |
|---|---|
| 30.07.2026 | Telefonla listeleme ucu (POST /tickets/by-phone) kaldırıldı. Sorgulama artık yalnızca talep numarası + telefon veya takip token'ı ile yapılır (bkz. bölüm 3). |
| 30.07.2026 | Tüm uçlara güvenlik sertleştirmesi uygulandı; hız sınırları ziyaretçi bazında işler hâle getirildi (X-Client-IP). |
| 29.07.2026 | Talep oluşturma (POST /tickets), bilgi düzeltme (POST /tickets/update) ve mahalle listesi (GET /neighborhoods) uçları eklendi. |