API Kuralları
Route'lar, header'lar, sayfalama, sorgular ve hatalar.
Bu sayfadaki kurallar ErtisAuth API'sinin her endpoint'i için geçerlidir.
Temel URL ve route'lar#
Bu dokümantasyondaki tüm örnekler temel URL olarak https://auth.example.com kullanır. ErtisAuth route'larını host'un kökünden sunar; onu bir yol öneki altında yayınlıyorsanız (örneğin bir gateway arkasında /api/v1), bu öneki her route'a ekleyin.
Route'lar üç gruba ayrılır:
| Grup | Route'lar | Membership'i belirleyen |
|---|---|---|
| Membership'e bağlı kaynaklar | /memberships/{membershipId}/users, /roles, /applications, /user-types, /providers, /webhooks, /mailhooks, /events, /code-policies, /codes, /active-tokens, /revoked-tokens | route |
| Token endpoint'leri | /generate-token, /refresh-token, /verify-token, /revoke-token, /me, /whoami, /verify-otp, /oauth/{slug}/login | X-Ertis-Alias header'ı (yalnızca membership gereken yerlerde) |
| Kurulum geneli | /memberships, /setup, /healthcheck, /ping | bir membership'e bağlı değil |
Membership izolasyonu#
Membership'e bağlı bir route'a yapılan istek, aynı membership'e ait bir token ile yapılmalıdır. Başka bir membership'in geçerli bir token'ı, yetkileri ne olursa olsun 403 AccessDenied ile reddedilir.
Header'lar#
| Header | Kullanan | Açıklama |
|---|---|---|
Authorization | neredeyse tüm endpoint'ler | Kullanıcılar için Bearer <access_token>, uygulamalar için Basic <application_id>:<secret>. Şema adında büyük/küçük harf ayrımı yapılmaz. |
X-Ertis-Alias | giriş endpoint'leri | Membership id'si. Alternatif header adları olarak Membership ve MembershipId da kabul edilir. |
X-IpAddress | giriş endpoint'leri | İsteğe bağlı. Son kullanıcının IP adresi; oturumla birlikte saklanır (istek sizin backend'inizden geliyorsa işe yarar). |
X-UserAgent | giriş endpoint'leri | İsteğe bağlı. Son kullanıcının user agent'ı; oturumla birlikte saklanır. |
X-Host | aktivasyon, şifre sıfırlama, OTP | E-postalardaki bağlantıların işaret ettiği sayfanın temel URL'si (bkz. Hesap Kurtarma). |
X-Setup-Token | /setup | Setup token'ı (bkz. Başlangıç). |
Content-Type | gövdesi olan istekler | application/json |
İstek ve yanıt gövdeleri#
- Gövdeler JSON'dır. Alan adları çoğu kaynakta
snake_case'dir (email_address,expires_in); sağlayıcılar, mail hook'lar ve kullanıcı tiplerinin bayraklarıcamelCasekullanır (defaultRole,mailSubject,isAbstract). Her referans sayfası tam alan adlarını gösterir. - Tarihler UTC cinsinden ISO 8601 dizeleridir.
- İstemci kabul ediyorsa yanıtlar Brotli ya da Gzip ile sıkıştırılır.
Durum kodları#
| Kod | ErtisAuth'taki anlamı |
|---|---|
200 OK | Gövdeli başarılı yanıt. Kısmen başarılı bir toplu silme de bunu döner (aşağıya bakın). |
201 Created | Bir kaynak ya da token oluşturuldu. Token'lar her zaman 201 ile döner. |
204 No Content | Gövdesiz başarılı yanıt (silme, çıkış). |
400 Bad Request | İstek hatalı biçimlendirilmiş ya da doğrulamadan geçemiyor. |
401 Unauthorized | Token eksik, geçersiz, süresi dolmuş ya da iptal edilmiş; ya da kimlik bilgileri yanlış. Bir WWW-Authenticate header'ıyla gelir. |
403 Forbidden | Çağıranın kimliği doğrulandı ama izni yok: eksik yetki, başka bir membership ya da devre dışı bir sağlayıcı. |
404 Not Found | Kaynak bu membership'te yok. |
409 Conflict | Bir tekrar (aynı slug, aynı username…), değişiklik içermeyen bir güncelleme, hâlâ kullanımda olan bir kaynak ya da zaten yapılmış bir setup. |
500 Internal Server Error | Beklenmeyen bir hata. Ayrıntılar yalnızca sunucu log'una yazılır. |
501 Not Implemented | İsteğin ihtiyaç duyduğu bir özellik yapılandırılmamış; ör. mail sağlayıcısı ya da aktivasyon mail hook'u yok. |
503 Service Unavailable | Harici bir sağlayıcıya (Google, Apple…) ulaşılamadı. |
Hatalar#
Hataların ortak bir biçimi vardır:
{
"message": "User not found in db by given _id: <66f1c0d2a4b5c6d7e8f90124>",
"errorCode": "UserNotFound",
"statusCode": 404
}Kodunuzda errorCode alanını kullanın; message insanlar içindir ve değişebilir. Tüm kodlar Hata Kodları sayfasında listelenir.
Doğrulama hataları sorunların listesini data alanında taşır:
{
"message": "Some fields are not validated, invalid or missing. Check response detail.",
"errorCode": "ModelValidationError",
"statusCode": 400,
"data": [ "Expires-in is required", "Secret key is required" ]
}Bir kullanıcının kullanıcı tipi şemasıyla doğrulanan özel alanlarındaki hatalar alanın adını verir:
{
"message": "String length can not be greater than 20",
"fieldName": "phone",
"fieldPath": "phone",
"errorCode": "FieldValidationException",
"statusCode": 400
}Aynı anda birden fazla alan geçersizse hepsi raporlanır:
{
"message": "…",
"errorCode": "ValidationException",
"statusCode": 400,
"errors": [
{ "message": "phone is required", "fieldName": "phone", "fieldPath": "phone" },
{ "message": "String length can not be less than 2", "fieldName": "firstname", "fieldPath": "firstname" }
]
}Geçerli bir ObjectId olmayan bir id 400 ParameterFormatError döner.
Kaynakları listeleme#
Liste endpoint'leri (GET /memberships/{membershipId}/users ve benzerleri) query parametreleriyle sayfalanabilir ve sıralanabilir:
| Parametre | Örnek | Açıklama |
|---|---|---|
skip | skip=20 | Atlanacak öğe sayısı. Negatif olamaz. |
limit | limit=10 | Dönecek en fazla öğe sayısı. Negatif olamaz. |
with_count | with_count=true | Eşleşen öğelerin toplam sayısını da count alanında döndürür. |
sort | sort=username ya da sort=sys.created_at desc | Sıralanacak alan; isteğe bağlı olarak ardından asc (varsayılan) ya da desc. |
curl 'https://auth.example.com/memberships/<membership_id>/users?skip=0&limit=2&with_count=true&sort=sys.created_at%20desc' \
-H 'Authorization: Bearer <access_token>'{
"count": 1250,
"items": [
{ "_id": "…", "username": "jane", "…": "…" },
{ "_id": "…", "username": "john", "…": "…" }
]
}with_count=true olmadan count hesaplanmaz.
Kaynakları sorgulama#
Kaynakların çoğunda, where alanında bir MongoDB sorgusu, select alanında isteğe bağlı bir projeksiyon alan bir POST …/_query endpoint'i vardır:
curl -X POST 'https://auth.example.com/memberships/<membership_id>/users/_query?limit=50&sort=lastname' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{
"where": {
"user_type": "customer",
"is_active": true,
"sys.created_at": { "$gte": "2026-01-01T00:00:00Z" }
},
"select": {
"username": 1,
"email_address": 1,
"firstname": 1
}
}'- Liste endpoint'lerinin sayfalama ve sıralama parametreleri burada da geçerlidir.
select, alanları1ya datrueile dahil eder,0ya dafalseile dışarıda bırakır.- Membership filtresi her zaman sunucu tarafından eklenir: bir sorgu başka bir membership'in verisini asla okuyamaz.
- JavaScript operatörleri (
$where,$function,$accumulator)400 InvalidQueryile reddedilir. password_hashgibi gizli alanlar ne döndürülebilir ne de filtrelerde ya da sıralamada kullanılabilir.- Kullanıcılarda isteğe bağlı
localequery parametresi (ör.locale=tr) sıralamanın collation'ını belirler; böylece adlar o dilde doğru sıralanır.
Aggregation#
Aktif token'lar ayrıca, JSON dizisi olarak aggregation pipeline aşamaları alan POST …/active-tokens/_aggregate endpoint'ini destekler. Membership filtresi sunucu tarafından ilk aşama olarak eklenir.
Yalnızca pipeline'dan geçen dokümanları dönüştüren aşamalara izin verilir: $match, $project, $addFields, $set, $unset, $group, $sort, $limit, $skip, $count, $unwind, $bucket, $bucketAuto, $sortByCount, $replaceRoot, $replaceWith, $sample, $setWindowFields ve $facet. Diğer tüm aşamalar, özellikle başka koleksiyonları okuyan ya da onlara yazanlar ($lookup, $graphLookup, $unionWith, $out, $merge), 400 UnsupportedAggregationStage ile reddedilir.
curl -X POST 'https://auth.example.com/memberships/<membership_id>/active-tokens/_aggregate' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '[
{ "$group": { "_id": "$user_id", "sessions": { "$sum": 1 } } },
{ "$sort": { "sessions": -1 } },
{ "$limit": 10 }
]'Kaynaklarda arama#
Kullanıcılar, roller, uygulamalar ve membership'lerde tam metin arama vardır:
curl 'https://auth.example.com/memberships/<membership_id>/users/search?keyword=lovelace&limit=10' \
-H 'Authorization: Bearer <access_token>'keyword zorunludur (aksi halde 400 SearchKeywordRequired). Sayfalama ve sıralama liste endpoint'lerindeki gibi çalışır.
Oluşturma ve güncelleme#
POSTbir kaynak oluşturur ve kaynakla birlikte birLocationheader'ı içeren201 Createddöner.PUT /{id}bir kaynağı günceller. Id her zaman route'tan gelir; gövdedeki bir_idyok sayılır.- Hiçbir şeyi değiştirmeyen bir güncelleme
409 IdenticalDocumentErrordöner. İstemciniz değişmemiş veri gönderebiliyorsa bunu başarı olarak değerlendirin. - Gövdede gönderilen bir
sysnesnesi yok sayılır.
Toplu silme#
Kullanıcılar, roller, uygulamalar, webhook'lar, mail hook'lar ve kod politikaları, koleksiyon route'una gövdesinde id'lerden oluşan bir JSON dizisi bulunan bir DELETE isteğiyle toplu olarak silinebilir:
curl -X DELETE 'https://auth.example.com/memberships/<membership_id>/users' \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '[ "66f1c0d2a4b5c6d7e8f90124", "66f1c0d2a4b5c6d7e8f90127" ]'| Sonuç | Yanıt |
|---|---|
| Hepsi silindi | 204 No Content |
| Hiçbiri silinmedi | 404 BulkDeleteFailed |
| Bir kısmı silindi | BulkDeletePartial hata gövdesiyle 200 OK |
200 döner. Bir 200 yanıtını tam başarı saymadan önce errorCode alanını kontrol edin.Dokümantasyonda bir hata mı buldunuz? Issue açın