Genel bakış
WiPoint Entegrasyon API'si https://api.wipoint.tr tabanında çalışan
JSON REST servisidir. Sürüm yola gömülüdür: /v1/…. Yalnız HTTPS kabul edilir.
01Müşteri anahtarı üretir
API Entegrasyon paketi olan müşteri, portalından anahtar oluşturur ve
client_id / client_secret ikilisini size verir.
02Token alırsınız
Gizli anahtarı 15 dakikalık erişim token'ına çevirirsiniz. Uzun ömürlü sır
iş çağrılarında hiç taşınmaz.
03Olayları dinlersiniz
Misafir bağlandı, kota doldu, nokta çevrimdışı — HMAC imzalı POST ile
kendi sisteminize düşer.
Ne yapılabilir
- Hotspot kullanıcısı oluşturma, listeleme, güncelleme, pasife alma
- Erişim profillerini (hız, süre, kota) okuma ve kullanıcıya atama
- Aktif oturumları görme ve sonlandırma
- Nokta durumu, eşzamanlı kullanıcı sayısı ve doluluk yüzdesi
- Olay bildirimleri için webhook tanımlama
Ne yapılamaz — bilinçli olarak
Cihaz yapılandırması (köprü, port, SSID), karşılama ekranı tasarımı, abonelik ve
ödeme işlemleri, KVKK metinleri ve 5651 delil paketi indirme API'de yoktur;
bunlar panelde, yetki ve denetim kaydıyla yapılır. Bir anahtar da yalnız kendisine
tanımlanan noktalara erişir — başka müşterinin verisine hiçbir koşulda ulaşamaz.
Erişim nasıl açılır
- Müşteri API Entegrasyon paketini satın alır (ya da WiPoint yöneticisi
firmaya elle yetki tanımlar).
- Hak firma seviyesinde durur ve kendi süresi vardır; şubelerin
hotspot aboneliğinden bağımsız yenilenir.
- Müşteri portalda Hotspot Yönetimi → API & Entegrasyon ekranından anahtar
üretir. Sihirbaz dört adımdır: ad, kapsam, yetkiler, kaynak IP.
client_secret yalnız üretim anında bir kez görünür. Kaybolursa
yenilenir; yenileme eski anahtarı anında geçersiz kılar, client_id değişmez.
Erişim ne zaman durur
Kimlik doğrulama — token exchange
İki adımlıdır: uzun ömürlü client_secret hiçbir iş çağrısında taşınmaz,
kısa ömürlü opak erişim token'ına çevrilir. Token sunucuda tutulur;
anahtar iptal edildiğinde ya da paket bittiğinde anında geçersiz olur.
curl -X POST https://api.wipoint.tr/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=wpi_9f4c21ab…" \
-d "client_secret=wps_7a1e…"
{
"access_token": "wpat_3f9c8e21…",
"token_type": "Bearer",
"expires_in": 900,
"scope": "nodes:read users:read users:write sessions:read"
}
Sonraki isteklerde:
Authorization: Bearer wpat_3f9c8e21…
Token'ı bellekte tutun, her istekte yeniden almayın — token ucu ayrıca
dakikada 10 istekle sınırlıdır.
Kaynak IP kuralı
Anahtar üretilirken en az bir kaynak IP tanımlanması zorunludur.
IP'siz anahtar oluşturulamaz.
Daha geniş bloklar (/16 gibi) reddedilir. Sınırlar, gerekçesi kayda
geçirilerek müşteri bazında gevşetilebilir. IP hem token alırken hem her
istekte doğrulanır; uymayan kaynak 403 ip_not_allowed alır ve
istek denetim günlüğüne yazılır.
Sabit çıkış IP'niz yoksa entegrasyon açılamaz. Bu bilinçli bir
güvenlik kararıdır: misafir kimlik verisine dokunan bir arayüzün nereden çağrıldığı
belirsiz kalamaz.
Anahtar kapsamı — çok şubeli müşteriler
Bir anahtar birden çok noktaya yetkilendirilebilir. Müşteri
üretim sırasında iki kapsamdan birini seçer:
Örnek: 50 şubeli bir zincir tek anahtarla tüm şubelerde hesap açar ve doluluk
görür; ikinci bir anahtar yalnız dört pilot şubeye yetkilendirilir. Kapsam dışı bir
noktaya istek 403 node_not_in_scope döner.
Yetkiler anahtarın tamamı için geçerlidir — aynı anahtar bir şubede
salt-okunur, diğerinde yazma yetkili olamaz. Farklı yetki gerekiyorsa ikinci anahtar üretilir.
Yetki seviyeleri
Anahtar üretilirken müşteri işaretler; token yanıtındaki scope alanı
fiilî yetkidir. Yetkisiz çağrı 403 insufficient_scope döner.
Pasife alma ayrı bir yetkidir: kota düzenleyen bir entegrasyon,
misafiri internetten atma hakkını kendiliğinden kazanmaz.
Başlarken
Token aldıktan sonra ilk anlamlı çağrı, erişebildiğiniz noktaları listelemektir:
curl https://api.wipoint.tr/v1/nodes \
-H "Authorization: Bearer wpat_3f9c8e21…"
Ardından bir noktada misafir hesabı açın:
curl -X POST https://api.wipoint.tr/v1/nodes/6bc7e95c-…/users \
-H "Authorization: Bearer wpat_3f9c8e21…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: oda-214-2026-08-26" \
-d '{
"username": "oda-214",
"password": "G3cici!Parola",
"full_name": "Ayşe Yılmaz",
"type": "guest",
"expires_in_minutes": 1440
}'
201 yanıtı:
{
"id": "9f4c21ab-…",
"username": "oda-214",
"status": "active",
"type": "guest",
"full_name": "AYŞE Y.",
"phone_masked": null,
"identity_verified": false,
"expires_at": "2026-08-27T09:00:00.000Z",
"created_at": "2026-08-26T09:00:00.000Z",
"created_via": "api"
}
Ağ koparsa: Idempotency-Key
Aynı anahtarla tekrar deneyin — 24 saat boyunca aynı yanıt döner ve
yanıta Idempotent-Replay: true başlığı eklenir. Kurallar:
- Yalnız başarılı yanıtlar saklanır. Hata alırsanız aynı anahtarla
düzeltilmiş gövdeyi gönderebilirsiniz — geçici bir hata 24 saat kalıcı hâle gelmez.
- Aynı anahtar farklı bir gövdeyle kullanılırsa
422 idempotency_key_reused.
- Aynı anahtarla eşzamanlı ikinci istek gelirse
409 idempotency_in_progress.
- Başlığı göndermezseniz idempotency çalışmaz; tekrar denemede aynı kullanıcı adı için
409 username_taken alırsınız (kayıt yine çiftlenmez).
Noktalar & doluluk
{
"data": [
{
"id": "6bc7e95c-…",
"name": "Kadıköy Şube",
"status": "online",
"last_seen_at": "2026-08-26T11:42:07.000Z",
"concurrent_limit": 50,
"active_users": 31,
"usage_percent": 62,
"subscription_status": "active",
"entitled": true,
"hotspot_servers": [{ "id": "…", "name": "lobi" }]
}
],
"next_cursor": null,
"has_more": false
}
/v1/nodes sayfalanmaz — kapsamınızdaki tüm noktalar tek
yanıtta gelir (has_more her zaman false). Şube başına ayrı
istek atmanız gerekmez.
status: online · offline · never
(tünel el sıkışmasından hesaplanır, eşik 15 dakika).
entitled: false olan şube listede görünür ama iş çağrılarında
node_not_entitled döner — aboneliği durmuştur.
Hotspot kullanıcıları
Zorunlu alanlar ve sınırlar
username, password ve full_name zorunludur.
5651 sayılı kanun gereği her internet erişimi bir kimliğe bağlanmak zorundadır;
doğrulamayı siz yaptığınız için kimlik sizden gelir. Eksikse
422 identity_required döner.
expires_in_minutes tavanı 1440 (24 saat). Süre dolunca
giriş kapanır, kayıt silinmez.
- Aynı kullanıcı adı ikinci kez gönderilirse
409 username_taken.
Kimlik alanları maskelidir
Okuma yanıtlarında telefon maskeli döner (0555 *** ** 67), ad-soyad
kısaltılır (AYŞE Y.), TCKN ve pasaport numarası hiç dönmez —
yalnız identity_verified bayrağı vardır. Eşleşme anahtarınız
username'dir; ham kimliğe ihtiyacınız olmaz. Ham veri panelde, gerekçe ve
denetim kaydıyla açılır.
Oturumlar
{ "ok": true, "path": "coa" }
path alanı işin gerçekte nasıl bittiğini söyler:
coa — cihaza RFC 5176 Disconnect-Request gönderildi ve yanıt alındı
device — CoA yanıtsız kaldı, oturum cihaz üzerinden düşürüldü
none — düşürülemedi; reason alanı sebebi taşır
"Gönderdim ama düşmedi" belirsizliğinde kalmayasınız diye bu alan
yanıtta yer alır.
Webhook'lar
Bir adres tanımlayın; seçtiğiniz olaylar HMAC-SHA256 imzalı JSON gövdeyle POST edilir.
Adres HTTPS ve genel internetten erişilebilir olmalıdır (iç ağ adresleri
reddedilir).
Olaylar
POST https://sizin-sisteminiz.com/wipoint-webhook
X-WiPoint-Signature: t=1755550000,v1=8f2c…
X-WiPoint-Event-Id: evt_8f2c…
X-WiPoint-Event: session.started
{
"id": "evt_8f2c…",
"event": "session.started",
"occurred_at": "2026-08-26T11:04:11.000Z",
"node_id": "6bc7e95c-…",
"data": {
"session_id": "81a0f3c2",
"username": "oda-214",
"ip": "10.24.7.112",
"mac": "A1:B2:C3:D4:E5:F6"
}
}
İmza doğrulama
İmzalanan metin <t> + "." + ham gövde'dir. t ile sizin
saatiniz arasındaki fark ±300 saniye içinde olmalı; karşılaştırmayı
sabit zamanlı yapın.
// Node.js
const crypto = require('node:crypto')
function wipointDogrula(rawBody, header, secret) {
const p = Object.fromEntries(header.split(',').map(x => x.trim().split('=')))
const t = Number(p.t)
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false
const beklenen = crypto.createHmac('sha256', secret)
.update(`${t}.${rawBody}`).digest('hex')
const a = Buffer.from(beklenen, 'hex')
const b = Buffer.from(p.v1 ?? '', 'hex')
return a.length === b.length && crypto.timingSafeEqual(a, b)
}
// PHP
function wipoint_dogrula(string $rawBody, string $header, string $secret): bool {
parse_str(str_replace(',', '&', $header), $p);
$t = (int)($p['t'] ?? 0);
if ($t === 0 || abs(time() - $t) > 300) return false;
$beklenen = hash_hmac('sha256', $t . '.' . $rawBody, $secret);
return hash_equals($beklenen, $p['v1'] ?? '');
}
// C#
static bool WipointDogrula(string rawBody, string header, string secret) {
var p = header.Split(',').Select(x => x.Trim().Split('='))
.ToDictionary(x => x[0], x => x[1]);
if (!long.TryParse(p["t"], out var t)) return false;
var simdi = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
if (Math.Abs(simdi - t) > 300) return false;
using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var beklenen = Convert.ToHexString(
h.ComputeHash(Encoding.UTF8.GetBytes($"{t}.{rawBody}"))).ToLowerInvariant();
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(beklenen), Encoding.UTF8.GetBytes(p["v1"]));
}
Yönetim uçları
Teslimat garantisi
Teslimat at-least-once'tır: ağ koptuğunda isteği almış olabilirsiniz
ama yanıt bize ulaşmamış olabilir; aynı olay tekrar gönderilir. Gövdedeki
id sabittir — alıcı tarafın idempotent olması gerekir.
2xx dışı yanıt ya da 10 saniye zaman aşımı → 5 deneme:
1 dk · 5 dk · 30 dk · 2 sa · 6 sa. Hepsi başarısızsa teslimat düşer ve
müşterinin panelinde "başarısız teslimat" olarak görünür.
Hata kodları & limitler
{
"error": { "code": "insufficient_scope",
"message": "Bu anahtarda users:write yetkisi yok." },
"request_id": "req_4b1e…"
}
Destek talebinde request_id paylaşın — istek denetim
günlüğünde birebir bulunur.
Sayfalama, hız sınırı, sürüm
- Sayfalama:
limit (varsayılan 50, tavan 200) +
cursor. Yanıt: data, next_cursor,
has_more. Ofset yoktur — kayan liste sorununu önlemek için.
- Hız sınırı: anahtar başına 120 istek/dakika; token ucu 10 istek/dakika.
Başarılı yanıtlar kalan hakkı
X-RateLimit-Remaining başlığında taşır.
- Sürüm sözü: yeni alan eklenmesi kırıcı değişiklik sayılmaz —
bilinmeyen alanları yok sayacak şekilde ayrıştırın. Alan kaldırma ya da anlam
değiştirme yalnız
/v2 ile olur; /v1 en az 12 ay yaşar.
Kullanımdan kaldırılacak uçlar en az 90 gün önce Deprecation ve
Sunset başlıklarıyla işaretlenir.
- Tüm zaman damgaları ISO 8601 UTC'dir.
Gizlilik ve 5651
Bu API kişisel veriye dokunur; üç kayıt katmanı istisnasız çalışır:
- Anahtar yaşam döngüsü — kim, ne zaman oluşturdu; hangi yetkiler ve
IP'ler verildi; kim iptal etti.
- Her istek —
request_id, anahtar, nokta, yol, sonuç,
kaynak IP, süre. Ayrı bir erişim günlüğünde 2 yıl saklanır ve
müşteri panelinden görülebilir.
- Her değişiklik — denetim kaydına
api kanalı, anahtar
kimliği ve kaynak IP ile yazılır.
API ile açılan bir hesabın ürettiği erişim kayıtları, kaydın kendi satırında
hangi anahtarla, hangi tarih-saatte ve hangi kaynak IP'den oluşturulduğunu taşır.
Resmî bir talepte bu bilgi delil paketinde görünür.
Sizin sorumluluğunuz: aldığınız verinin saklanması, silinmesi ve
paylaşılması KVKK kapsamında size aittir. client_secret ve webhook
secret değerlerini kaynak koda gömmeyin, sürüm sistemine koymayın.
İndirilebilir kaynaklar