Dokümantasyon
API Referansı
Tüm HTTP uçları, kimlik, scope’lar ve Node.js örnekleri. İndirilebilir docs.md de mevcut.
Base URL
EDGE_BASE = projenin data_plane_url (örn. https://cdn-tr-01.liap.cloud)
Kalıp: {EDGE_BASE}/{service}/{path}
Proje X-Liap-Key (liap_live_…) ile seçilir — path’te UUID yok.
Servisler: auth, db, storage, realtime, functions, search, notifications, monitor, analytics, ai, webhooks, secrets
GET {EDGE}/health — kenar sağlığı (auth yok).
const EDGE = process.env.LIAP_EDGE
const API_KEY = process.env.LIAP_API_KEY
const res = await fetch(`${EDGE}/db/tables/todos/rows`, {
headers: { 'X-Liap-Key': API_KEY },
})Kimlik doğrulama
İstek: {EDGE}/{service}/… + X-Liap-Key. Proje UUID yazılmaz. JSON’da project_id yok.
API key (liap_live_…) projeyi seçer — kullanıcı oturumu değildir.
Kayıt/giriş/anonymous/refresh: yalnız X-Liap-Key.
/auth/me, MFA, passkey, logout: X-Liap-Key + Authorization: Bearer lca_… birlikte.
401 → POST /auth/refresh ({ refresh_token } + X-Liap-Key). Rotation: eski çift geçersiz.
| Method | Path | Açıklama |
|---|---|---|
| 401 | invalid key / missing scope | Yetkisiz |
| — | data:read / data:write | db, search, notifications, analytics |
| — | storage:read / storage:write | storage |
| — | realtime:subscribe | SSE / WS / presence / broadcast |
| — | functions:invoke | functions |
| — | notifications:send | POST /notifications/email — yalnız sunucu anahtarı |
| — | auth:admin | monitor status/crashes, admin |
fetch(`${EDGE}/db/tables/todos/rows`, {
headers: { 'X-Liap-Key': API_KEY },
})Proje API anahtarından çözülür; path’te UUID gerekmez. Dashboard oturumu X-Liap-Project kullanabilir.
Auth
Yanıt: access_token (lca_…), refresh_token (lcr_…), expires_in (900), user — aynı alanlar tokens altında da gelir.
user.id UUID; user.user_metadata (alias metadata) kullanıcı yazabilir; user.app_metadata yalnız admin.
Kayıt: email, password, name?, user_metadata? (alias data/metadata). Kayıt sonrası profiles.id = user.id.
MFA açıksa login 200 + mfa_required + mfa_token → POST /auth/mfa/verify.
| Method | Path | Açıklama |
|---|---|---|
| POST | /auth/register | Kayıt (+ user_metadata) |
| POST | /auth/login | Giriş (Key) |
| GET | /auth/me | Mevcut kullanıcı (Key + Bearer lca_) |
| PATCH | /auth/me | name + user_metadata (kalıcı) |
| POST | /auth/refresh | Token yenile (Key + refresh_token) |
| POST | /auth/logout | Çıkış (Key + Bearer; boş gövde OK) |
| POST | /auth/anonymous | Anonim oturum |
| GET | /auth/users | Admin liste (dashboard) |
| PATCH | /auth/users/{id} | Admin: role / metadata / verified |
| GET | /auth/user-fields | Ek alan şeması |
| PUT | /auth/user-fields | Ek alan şeması yaz |
| GET | /auth/roles | Proje rol listesi |
| PUT | /auth/roles | Rolleri kaydet |
| POST | /auth/mfa/setup | TOTP kurulum |
| POST | /auth/mfa/verify | MFA doğrula |
| POST | /auth/passkey/register/begin | Passkey begin |
| GET | /auth/oauth/google/start | OAuth başlat |
| POST | /auth/recover | Şifre sıfırlama iste |
const session = await fetch(`${EDGE}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Liap-Key': API_KEY },
body: JSON.stringify({
email: '[email protected]',
password: 'demo12345',
name: 'Demo',
user_metadata: { username: 'demo' },
}),
}).then(r => r.json())
const token = session.access_token
const me = await fetch(`${EDGE}/auth/me`, {
headers: { 'X-Liap-Key': API_KEY, Authorization: `Bearer ${token}` },
}).then(r => r.json())
const profiles = await fetch(
`${EDGE}/db/tables/profiles/rows?filter=id.eq.${session.user.id}`,
{ headers: { 'X-Liap-Key': API_KEY } },
).then(r => r.json())Database
Document tablolar: id + data JSONB. İlişkisel tablolar: gerçek kolonlar, API'de data olarak sarılır.
GET /db/schema · POST /db/tables. Auth profiles.id = auth user UUID.
Insert/PATCH gövdesi: { "data": { ... } }.
filter=alan.op.değer · select · order · limit/offset.
| Method | Path | Açıklama |
|---|---|---|
| GET | /db/schema | Şema grafiği |
| POST | /db/tables | Tablo oluştur |
| GET | /db/tables | Tablo listesi |
| GET | /db/tables/{t}/rows | Satır listesi |
| POST | /db/tables/{t}/rows | Satır ekle { data } |
| GET | /db/tables/{t}/rows/{id} | Tek satır |
| PATCH | /db/tables/{t}/rows/{id} | Merge güncelle { data } |
| DELETE | /db/tables/{t}/rows/{id} | Sil (204) |
| GET | /db/tables/{t}/rls | RLS oku |
| PUT | /db/tables/{t}/rls | RLS yaz |
| POST | /db/rpc | JSON-RPC (db.tables / db.list / …) |
| POST | /db/query | Ham SQL |
| POST | /db/graphql | GraphQL (sınırlı şema) |
const headers = { 'X-Liap-Key': API_KEY, 'Content-Type': 'application/json' }
const created = await fetch(`${EDGE}/db/tables/todos/rows`, {
method: 'POST',
headers,
body: JSON.stringify({ data: { title: 'Merhaba', done: false } }),
}).then(r => r.json())
const rows = await fetch(`${EDGE}/db/tables/todos/rows?filter=done.eq.false&select=title,done`, {
headers: { 'X-Liap-Key': API_KEY },
}).then(r => r.json())Storage
Public okuma: GET {EDGE}/storage/objects/{bucket}/{shortId} — auth yok, proje id yok.
Yazma: PUT {EDGE}/storage/objects/{bucket}/{key} + X-Liap-Key, raw body. Yanıt id = public short_id.
Boyut: ?w= & ?h= veya ?g=. Iframe: GET {EDGE}/upload?key=liap_live_…&bucket=…
DELETE bucket 204 (gövde yok).
| Method | Path | Açıklama |
|---|---|---|
| GET | /storage/buckets | Bucket listesi |
| POST | /storage/buckets | Bucket oluştur { name, public } |
| DELETE | /storage/buckets/{bucket} | Bucket sil (204) |
| GET | /storage/objects/{bucket} | Object listele (?prefix=) |
| PUT | /storage/objects/{bucket}/{key} | Yükle (raw body) |
| GET | /storage/objects/{bucket}/{key} | İndir (API) |
| DELETE | /storage/objects/{bucket}/{key} | Object sil |
| POST | /storage/signed/{bucket}/{key} | İmzalı URL |
| GET | /storage/objects/{bucket}/{shortId} | Public URL (auth yok) |
| GET | /{shortId} | Eski kısa URL |
| POST | /storage/multipart | Multipart başlat |
| GET | /upload | Upload iframe (absolute) |
import { readFileSync } from 'fs'
const up = await fetch(`${EDGE}/storage/objects/data/logo.png`, {
method: 'PUT',
headers: { 'X-Liap-Key': API_KEY, 'Content-Type': 'image/png' },
body: readFileSync('./logo.png'),
}).then(r => r.json())
console.log(`${EDGE}/storage/objects/data/${up.id}`)Realtime
| Method | Path | Açıklama |
|---|---|---|
| GET | /realtime/stream?table= | SSE (tablo WAL) |
| WS | /realtime/ws?table= | WebSocket |
| GET | /realtime/presence?channel= | Presence oku |
| POST | /realtime/presence | Presence yaz |
| POST | /realtime/broadcast | Broadcast (204) |
const res = await fetch(`${EDGE}/realtime/stream?table=todos`, {
headers: { 'X-Liap-Key': API_KEY },
})
// stream res.body …
// WS: wss://{EDGE}/realtime/ws?table=todos Authorization: Bearer lca_…Functions
| Method | Path | Açıklama |
|---|---|---|
| GET | /functions | Liste |
| POST | /functions/{name} | Invoke |
| PUT | /functions/{name} | Deploy kaynak |
| DELETE | /functions/{name} | Sil |
| GET | /functions/runtime | Runtime |
| POST | /functions/jobs | Arka plan iş |
const out = await fetch(`${EDGE}/functions/hello`, {
method: 'POST',
headers: { 'X-Liap-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ a: 1, b: 2 }),
}).then(r => r.json())
console.log(out.result, out.logs)Search
| Method | Path | Açıklama |
|---|---|---|
| GET | /search/{table}?q= | Tam metin |
| POST | /search/semantic | Semantic |
const hits = await fetch(
`${EDGE}/search/todos?q=rapor&limit=20`,
{ headers: { 'X-Liap-Key': API_KEY } },
).then(r => r.json())Bildirimler
Push (Expo, FCM, APNs, Web Push), e-posta (Resend) ve uygulama içi bildirimler. Sağlayıcı anahtarları dashboard → API Bilgileri'nde. Ayrıntılı rehber: /docs/notifications.
API key + Bearer lca_ birlikte gönderildiğinde cihaz kaydı ve gelen kutusu oturumdaki kullanıcıya bağlanır.
| Method | Path | Açıklama |
|---|---|---|
| GET | /notifications | Kullanıcının bildirimleri (Bearer) |
| POST | /notifications | Uygulama içi bildirim oluştur (data:write) |
| POST | /notifications/{id}/read | Okundu (Bearer) |
| POST | /notifications/devices | { platform?, token } — expo | fcm | apns | webpush (Bearer veya sunucu + user_id) |
| GET | /notifications/devices | Cihaz özeti { total, users, by_platform } |
| POST | /notifications/push | { title, body?, user_id?, tokens?, data?, sound?, badge?, channel_id? } (data:write) |
| POST | /notifications/email | { to, subject, html?, text?, from?, cc?, bcc?, reply_to? } (notifications:send) |
| GET | /notifications/vapid-public-key | Web Push VAPID public anahtarı |
// Push — kayıtlı cihazlara (Expo / FCM / APNs / Web Push)
await fetch(`${EDGE}/notifications/push`, {
method: 'POST',
headers: { 'X-Liap-Key': SERVER_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Siparişin yolda', body: '#1042', user_id: userId, data: { orderId: 1042 } }),
})
// E-posta — projenin Resend anahtarıyla (notifications:send)
await fetch(`${EDGE}/notifications/email`, {
method: 'POST',
headers: { 'X-Liap-Key': SERVER_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
from: 'Destek <[email protected]>',
to: '[email protected]',
subject: 'Hoş geldin',
html: '<h1>Merhaba</h1>',
}),
})E-posta hataları: 412 Resend bağlı değil · 400 geçersiz alan / Resend reddi · 429 hız sınırı · 502 Resend'e ulaşılamadı.
Live (canlı log)
Edge'e gelen her istek proje bazında kaydedilir; istek gövdesi ve query string kaydedilmez. Dashboard oturumu veya auth:admin kapsamlı API key gerekir.
Başarılı veri değişiklikleri kind: "change" ve okunur bir label taşır (ör. "API bilgisi güncellendi: RESEND_API_KEY").
Konum Cloudflare ziyaretçi başlıklarından gelir (Managed Transforms → Add visitor location headers).
| Method | Path | Açıklama |
|---|---|---|
| GET | /live?since={seq} | { seq, events, stats, edge } anlık görüntü |
| GET | /live/stream | SSE: hello · log · stats (2 sn) |
| GET | /public/traffic | Kimliksiz SSE (hit) — IP/yol yok, konum ~11 km |
| GET | /public/traffic/recent?since={seq} | Aynı akışın yoklama sürümü |
const res = await fetch(`${EDGE}/live/stream`, { headers: { 'X-Liap-Key': ADMIN_KEY } })
const reader = res.body.getReader()
const decoder = new TextDecoder()
for (;;) {
const { value, done } = await reader.read()
if (done) break
process.stdout.write(decoder.decode(value)) // event: log\ndata: {...}
}Webhook’lar
Olay adları: db.insert / db.update / db.delete (insert/update/delete de kabul).
HTTPS veya http://127.0.0.1 / http://localhost.
| Method | Path | Açıklama |
|---|---|---|
| GET | /webhooks | Liste |
| POST | /webhooks | Oluştur { url, events } |
| DELETE | /webhooks/{id} | Sil (204) |
| POST | /webhooks/dispatch | Test gönder |
await fetch(`${EDGE}/webhooks`, {
method: 'POST',
headers: { 'X-Liap-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
url: 'https://example.com/hook',
events: ['db.insert', 'db.update'],
}),
})API Bilgileri / flag
Dashboard'daki API Bilgileri bu servisi kullanır: EXPO_ACCESS_TOKEN, RESEND_API_KEY, RESEND_FROM. Değerler yalnız edge'de saklanır; listede maskelenir (RESEND_FROM gibi gizli olmayan ayarlar açık döner).
| Method | Path | Açıklama |
|---|---|---|
| GET | /secrets | Liste (değerler maskeli) |
| PUT | /secrets/{name} | Yaz { value } |
| DELETE | /secrets/{name} | Sil (204) |
| GET | /secrets/flags | Flag listesi |
| PUT | /secrets/flags/{key} | Flag yaz |
| DELETE | /secrets/flags/{key} | Flag sil (204) |
await fetch(`${EDGE}/secrets/STRIPE_KEY`, {
method: 'PUT',
headers: { 'X-Liap-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ value: 'sk_live_…' }),
})Analytics / Monitor
Tarayıcıda POST /analytics/events kullanmayın — uBlock/EasyList keser (HTTP 0 Failed to fetch).
Tarayıcı ve SDK: POST /monitor/events ve GET /monitor/summary (data:write / data:read).
/analytics/events ve /analytics/summary curl alias olarak durur.
GET /monitor/status ve /monitor/crashes → auth:admin.
| Method | Path | Açıklama |
|---|---|---|
| GET | /monitor/status | Servis sağlığı (auth:admin) |
| POST | /monitor/events | Olay yaz (önerilen) |
| GET | /monitor/summary | Özet metrikler (önerilen) |
| POST | /analytics/events | Alias — reklam engelleyici keser |
| GET | /analytics/summary | Alias özet |
| POST | /monitor/crashes | Crash yaz (auth:admin) |
| GET | /monitor/crashes | Crash liste (auth:admin) |
await fetch(`${EDGE}/monitor/events`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Liap-Key': API_KEY },
body: JSON.stringify({ name: 'page_view', properties: { path: '/' } }),
})
const summary = await fetch(`${EDGE}/monitor/summary`, {
headers: { 'X-Liap-Key': API_KEY },
}).then(r => r.json())Tam örnek: Todo
const EDGE = process.env.LIAP_EDGE
const API_KEY = process.env.LIAP_API_KEY
const headers = { 'X-Liap-Key': API_KEY, 'Content-Type': 'application/json' }
const row = await fetch(`${EDGE}/db/tables/todos/rows`, {
method: 'POST',
headers,
body: JSON.stringify({ data: { title: 'Liap ile ilk kayıt', done: false } }),
}).then(r => r.json())
const list = await fetch(`${EDGE}/db/tables/todos/rows?limit=20`, {
headers: { 'X-Liap-Key': API_KEY },
}).then(r => r.json())
await fetch(`${EDGE}/db/tables/todos/rows/${row.id}`, {
method: 'PATCH',
headers,
body: JSON.stringify({ data: { done: true } }),
})Ham markdown: /docs.md indir. Kaynak: docs/api-reference.md