01 · GET /config — Config Çekme Sözleşmesi
Görev:
00 · AUTH'un döndürdüğütokenile cihazın tam config'ini (tema + ekranlar + gruplar + metinler) sunucudan çeker; SDK config'i parsel edip onay ekranını (banner/manager/detail) kurar.Ne zaman çalışır: AUTH'un yanıtında
decision.updateRequired === trueolduğunda. Değilse (içerik değişmedi) bu adım atlanır; cihazdaki mevcut config önbellekten kullanılır.Bu dosyadan sonra kullanıcı onay ekranında bir seçim yaptığında
02 · POST_CONSENT'e geçersiniz.
1. Genel Bakış
GET /config, açılış döngüsünün orta halkasıdır: AUTH onu besler (token verir), o da onay kaydına zemin hazırlar (UI'ı kurar, aynı token'ı taşır).
SDK sunucuya:
- Kimlik taşır → path'te
consentId+ header'daX-Consent-Token(+ gövdede opsiyonellocale/sdkVersion)
Sunucu karşılığında:
- Tam config gövdesi döndürür →
config(tema, ekranlar, gruplar, metinler; detay §5.2) - Çerçeve (envelope) döndürür →
success/code/consentId/deliveredAt/contentVersion/tokenConsumed
Tasarım felsefesi: Bu bir OKUMA (read) işlemidir — durumu değiştirmez, idempotent'tir. AUTH hafif tutulur (yalnız versiyonlar + token + decision); tam config yalnızca gerçekten gerektiğinde bu adım ile çekilir. Böylece büyük çoğunluk açılışta config hiç transfer edilmez → açılış hızlı, veri tasarruflu, gecikme düşük.
GET /config, AUTH'ın "gerekli mi?" sorusuna verdiği cevabı (
decision.updateRequired) hayata geçiren adımdır.updateRequired === falseise bu adımı atlayın, cihazdaki mevcut config'i kullanın.
2. Döngüdeki Yeri
AUTH (00) GET /config (BU) POST_CONSENT (02)
kimlik + localState ──▶ token ─▶ tam config ────▶ onay kaydı
│ token │ parse → UI kur │ consent + localState
└── decision.updateRequired ──┘ (aynı token) │
│
bir sonraki AUTH ◀─────────────── localState geri besleme
| Adım | Koşul | SDK davranışı |
|---|---|---|
| 00 — AUTH | Her açılışta | Kimlik + localState gönder; versiyon + token + decision al |
| 01 — GET /config (bu adım) | decision.updateRequired === true | Token ile tam config indir, parsel et, önbelleğe yaz, UI'ı yeniden kur |
| 02 — POST_CONSENT | Kullanıcı onay ekranında karar verirse | Aynı token ile onay eylemini post et |
Neden iki aşamalı? İçerik değişmiyorsa config hiç transfer edilmez. Değişiyorsa, AUTH'ın verdiği token ile tek istekte tam config çekilir — ayrı bir anahtar imzalama derdi yoktur (o iş AUTH'ta yapıldı).
3. Endpoint & Güvenlik
3.1 Endpoint
| Özellik | Değer |
|---|---|
| Method | POST |
| Path | /v2/consent/{consentId}/config |
| Base URL | {{SDK_BASE_URL}} |
| Gövde formatı | application/json (UTF-8) |
| Timeout | 15 sn |
| Idempotent | Evet — okuma işlemidir; aynı istek tekrarlandığında aynı config'i döndürür (retry güvenli). |
Neden
POST(RESTGETdeğil)? İki neden: (1) SDK'nın üç sözleşmesi tutarlı biçimdePOST'tur — tek transport modeli. (2)GET, ara katmanlarda (proxy/CDN/tarayıcı) önbelleğe alınabilir; token + kimlik taşıyan hassas bir istek önbelleğe alınmamalıdır.POSTbunu garanti eder. Adımdaki "GET" okuma semantiğidir, HTTP fiilini değil.
3.2 Güvenlik (token-bearer — imza/nonce YOK)
GET /config, AUTH'taki HMAC + nonce + timestamp modelini kullanmaz. Kimlik yalnızca AUTH'tan alınan imzalı, oturum bazlı token ile yapılır:
| Header | Değer / Açıklama |
|---|---|
Content-Type | application/json |
X-Consent-Token | AUTH yanıtındaki token (imzalı, oturum bazlı, tokenExpiresIn'e bağlı). Örnek: cfg_t_8a3f5c2d1e0b. |
- Doğrulama (sunucu): (1) token biçimi/doğrulaması geçerli mi? (2) süresi doldu mu? (3) daha önce tüketildi mi? (4) token'ın bağlı olduğu
consentId== path/gövdeconsentIdmi? → her ihlal ilgili401/404kodu. - Replay: Okuma işlemi zararsızdır (aynı config'in tekrar çekilmesi idempotent'tir). Bu yüzden
nonce/timestamp gerekmez; replay koruması token'ın bağlı olduğu consentId + sınırlı geçerlilik penceresi (tokenExpiresIn) + oturum bazlı tüketimi (§4) ile sağlanır.
POST_CONSENT ile fark (önemli):
02 · POST /consentbir YAZMA işlemidir → durumu değiştirir, mükerrer yazma riski taşır → bu yüzden HMAC +nonce+ timestamp zorunludur.GET /configbir OKUMA işlemidir → idempotent + retry-tolerant → bearer token yeterlidir, ek imza/nonce eklenmez. Bu ayrım, SDK'nın ağ kesintisi gibi okuma hatasında rahatça retry yapabilmesini sağlar; nonce tabanlı bir okuma ise retry'ı reddederdi.
4. İstek (request)
Gövde minimaldir: kimlik path'te, token header'dadır. Gövde yalnızca opsiyonel çözümleme/telemetri alanlarını taşır. camelCase zorunludur.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
consentId | string | Evet | Onay kaydı kimliği (ör. ck_mobildev_0001). Path'teki {consentId} ile birebir aynı olmalıdır; sunucu path ↔ gövde ↔ token üçlüsünü çapraz-doğrar, uyumsuzluk → 401 INVALID_TOKEN. |
locale | string (BCP-47) | Hayır | Kullanıcı tercih edilen dil (ör. tr-TR). Response'u daraltmaz (bkz. Not 1); telemetri + SDK'ın aktif dil çözümlemesine ipuç. Yoksa SDK behavior.defaultLanguage'i kullanır. |
sdkVersion | string (semver) | Hayır | SDK sürümü. AUTH çağrısıyla korelasyon + uyumluluk/telemetri. |
Not 1 —
localeresponse'u değiştirmez: Sunucu, requestlocale'i ne olursa olsun tam config'i (tümlocalizationblokları) döndürür. Dil çözümlemesi SDK tarafında yapılır (behavior.defaultLanguage+ kullanıcı tercihi +availableLanguages). Böylece response deterministik kalır ve SDK, dil değiştirdiğinde yeniden istek atmak zorunda kalmaz.Not 2 — Token yalnız header'dadır: Token gövde içine yazılmaz;
X-Consent-Tokenheader'ında taşınır (§3.2). Bu yüzden gövde küçük ve sade kalır.
4.1 Örnek İstek
{
"consentId": "ck_mobildev_0001",
"locale": "tr-TR",
"sdkVersion": "1.4.0"
}
Ayrıca header'da:
X-Consent-Token: cfg_t_8a3f5c2d1e0b. Bu örneğin aynısı ayrıca[01-config.request.json](./01-config.request.json)dosyasında yer alır.
5. Yanıt (response)
Response, diğer sözleşmelerle tutarlı bir envelope + içinde tam config taşır. HTTP 200 → başarılı; 4xx/5xx → ortak hata envelope'u.
5.1 Envelope Alanları (200)
| Alan | Tip | Açıklama |
|---|---|---|
success | boolean | true — config başarıyla getirildi. (Hatalarda false ortak envelope döner, bkz. §7.) |
code | string | Kod (başarıda OK). |
consentId | string | Çözülen consentId (eko; log + doğrulama). |
deliveredAt | string (ISO 8601 UTC) | Config'in sunucu tarafından servis edildiği an (audit/telemetri). |
contentVersion | string | Config'in içerik versiyonu. SDK bunu cihazdaki installedContentVersion'ıyla karşılaştırıp reprompt kararını hızla üretebilir. |
tokenConsumed | boolean | Bu çağrı token'ı tüketmiş midir? GET /config'de false (okuma token'ı bitirmez). SDK bu değere bakarak token'ın onay adımı için hâlâ geçerli olduğunu bilir (bkz. §6). |
config | object | TAM config gövdesi = §5.2'deki blok yapısı. |
5.2 config Gövdesi (üst düzey yapı)
config, uygulamanızın onay deneyiminin tamamını tanımlayan tek JSON'dır. Üst düzey bloklar:
| Blok | İçerik |
|---|---|
schemaVersion | "2.0" — SDK feature-gate. |
meta | consentId / organization / contentVersion / contentMode / generatedAt. |
behavior | defaultLanguage / availableLanguages / allowLanguageChange / showConsentId / promptATTdialog / displayATTStatus / retrigger{…}. |
theme | scheme + light/dark renk token'ları + typography + radius + spacing. |
banner | layout / logo / title / description / buttons.list[] (ilk onay ekranı). |
manager | title / showBack / groupRow / groups[] (her grupta consentKeys[] + items[]) / footer.actions[] (ana tercih ekranı). |
detail | showBack / sections / links[] / actions[] (öğe/grup detay ekranı). |
localization | tr-TR / en-US / de-DE — tüm metinlerin i18n anahtarları. |
Alt bloklarda öne çıkanlar:
manager.groups[]— izin kategorileri:essential/functionality/targeting/tracking. Her grupta:id,titleLangKey,descLangKey,isEssential,lockState,defaultState,consentKeys[](etiketlere karşılık gelen key listesi) veitems[](o gruptaki teknoloji/vendor satırları — bilgilendirme amaçlı, etiket key taşımaz).- Tema token'ları — Bileşenler renk hex değerini değil, token ismin referans verir (
primary,surface,onSurface…). Aynı token setilightvedarkbloklarında ayrı değerlerle tanımlanır → tek config ile açık+koyu mod. consentKeysgrup seviyesindedir —items[]yalnız teknoloji/amacı açıklar; onay durumu grubun kimliğinde taşır. Etiketlere dağıtım SDK tarafında yapılır (02 adımında, §6).
5.3 Örnek Yanıt (örnek config gövdesi — özet)
Aşağıda envelope + config'in ilk kısımları gösterilir. Üretimdeki config, gerçek markaya/müşteriye göre doldurulur; buradaki değerler örnek (placeholder) amaçlıdır.
{
"success": true,
"code": "OK",
"consentId": "ck_mobildev_0001",
"deliveredAt": "2026-09-20T11:33:30Z",
"contentVersion": "2",
"tokenConsumed": false,
"config": {
"schemaVersion": "2.0",
"meta": {
"consentId": "ck_mobildev_0001",
"organization": "Mobildev",
"contentVersion": "2",
"contentMode": "sample",
"generatedAt": "2026-09-18T10:20:00Z"
},
"behavior": {
"defaultLanguage": "tr-TR",
"availableLanguages": ["tr-TR", "en-US", "de-DE"],
"allowLanguageChange": true,
"showConsentId": false,
"promptATTdialog": true,
"displayATTStatus": false,
"retrigger": { "onConfigChange": true, "onMajorChange": true, "interval": null }
},
"theme": {
"scheme": "system",
"light": { "primary": "#1976D2", "onPrimary": "#FFFFFF", "surface": "#F6F8FB", "onSurface": "#1F2328" },
"dark": { "primary": "#8AB4F8", "onPrimary": "#0B2E5C", "surface": "#1B2027", "onSurface": "#E6E9EF" },
"typography": { "family": "system-ui, sans-serif", "title": { "size": 18, "weight": 700 }, "body": { "size": 14, "weight": 400 } },
"radius": 16,
"spacing": 20
},
"banner": {
"layout": { "type": "bottomSheet", "showDragHandle": true, "maxHeightPercent": 82 },
"logo": { "show": true, "src": "", "size": 46, "position": "center" },
"title": { "langKey": "banner_title" },
"description": { "langKey": "banner_description", "maxLines": 6, "format": "plain" },
"buttons": {
"direction": "vertical", "gap": 10, "height": 50, "stretch": true,
"list": [
{ "id": "accept_all", "style": "filled", "langKey": "banner_btn_accept_all", "colorToken": "primary" },
{ "id": "reject_all", "style": "outlined", "langKey": "banner_btn_reject_all", "colorToken": "primary" },
{ "id": "modify", "style": "text", "langKey": "banner_btn_modify", "colorToken": "primary" }
]
}
},
"manager": {
"title": { "langKey": "manager_title" },
"showBack": true,
"groupRow": { "showToggle": true, "showChevron": true, "showIcon": false },
"groups": [
{ "id": "essential", "lockState": true, "defaultState": "on",
"consentKeys": ["security_storage"],
"items": [ { "id": "session", "scope": "first_party" }, { "id": "fraud", "scope": "first_party" } ] },
{ "id": "functionality", "lockState": null, "defaultState": "off",
"consentKeys": ["personalization_storage", "functionality_storage"] },
{ "id": "targeting", "lockState": null, "defaultState": "off",
"consentKeys": ["ad_storage", "ad_user_data", "ad_personalization"] },
{ "id": "tracking", "lockState": null, "defaultState": "off",
"consentKeys": ["analytics_storage"] }
],
"footer": { "position": "sticky", "actions": [
{ "id": "accept_all", "style": "outlined", "langKey": "banner_btn_accept_all", "colorToken": "primary" },
{ "id": "save", "style": "filled", "langKey": "manager_btn_save", "colorToken": "primary" }
] }
},
"detail": { "showBack": true, "sections": { "showTechnology": true, "showPurpose": true, "showToggle": true }, "links": [], "actions": [ { "id": "save", "style": "filled", "langKey": "manager_btn_save", "colorToken": "primary" } ] },
"localization": { "tr-TR": { "…": "…" }, "en-US": { "…": "…" }, "de-DE": { "…": "…" } }
}
}
localizationbloğu, config'deki tümlangKeyalanlarına karşılık gelen metindir (banner, manager, gruplar, öğeler, runtime durum metinleri). Her dil bloğu aynı anahtar setine sahiptir;behavior.availableLanguages'indeki her dil için bir blok zorunludur. Eksik anahtar → SDKdefaultLanguage'ye fallback eder.Bu örneğin aynısı, envelope ve tam config gövdesiyle birlikte ayrıca
[01-config.response.json](./01-config.response.json)dosyasında yer alır. Not: bu.mdiçindelocalizationbloğu yer tasarrufu için özetlenmiş görünür;.jsondosyasında üç dilin tam metin setiyle geçer.
6. Token Yaşam Döngüsü (KRİTİK)
Token = imzalı, oturum bazlı bir kimlik (session credential). "Tek kullanımlık" ifadesi tek HTTP çağrısı değil, tek consent-oturumu anlamına gelir. Döngü, aynı token'ın hem bu adımda hem onay adımında kullanılmasını gerektirir.
| Özellik | Açıklama |
|---|---|
| Köken | AUTH (00), her başarılı çağrısında bir token üretir. Bir AUTH → bir token. |
| Bağlılık | Token belirli bir consentId'ye bağlıdır. Başka bir consentId ile kullanılamaz (→ INVALID_TOKEN). |
| Geçerlilik penceresi | tokenExpiresIn (sn; varsayılan 300 = 5 dk). Pencere dolunca token geçersiz olur (TOKEN_EXPIRED). |
| GET /config (bu adım, okuma) | Token'ı tüketmez. Config çekilir; token oturumda yaşamaya devam eder, tokenConsumed: false döner. Aynı pencerede yeniden denenebilir (retry güvenli). |
| POST /consent (02, yazma) | Başarılı onay kaydı, oturumu tamamlar → token'ı tüketir. Sonrası için token ölüdür. |
| Yaşam sonu | Pencere dolunca veya onay kaydı oturumu kapatınca token geçersizleşir → sonraki etkileşim yeni AUTH ile başlar. |
AUTH ──üretir──▶ TOKEN (consentId'ye bağlı, 300 sn)
│
┌───────────┴───────────┐
│ (okuma) │ (yazma)
▼ ▼
GET /config POST_CONSENT
token TÜKELENMEZ token TÜKETİLİR (oturum kapanır)
(retry serbest) ──────────────────────────▶
│ │
└──► pencere dolunca / oturum kapanınca ──► YENİ AUTH
Sonuç: AUTH'tan gelen token, bir consent oturumu boyunca hem config okuma (tüketmez) hem onay yazma (tüketir) için geçerlidir. Bu adımı başarıyla tamamladıktan sonra aynı token'la
02 · POST_CONSENT'e güvenle geçebilirsiniz. Token yalnızca gerçek durum değişikliği (onay kaydı) sonucunda veya süresi dolunca ömürden düşer.
7. Hata Kodları
Hatalarda ortak gövde döner: { success:false, code, message, retryable, requestId }. (message teşhis metnidir; UI'da gösterilmez — kullanıcıya gösterilecek metin localization bloklarından gelir, ör. error_state.)
GET /config bir token-bearer okuma olduğu için, AUTH'taki HMAC bağlı kodlar (SIGNATURE_MISMATCH, REPLAY_DETECTED…) bu sözleşmede yoktur. Yalnız token/consent kaynaklı kodlar:
code | HTTP | retryable | Açıklama / SDK müdahalesi |
|---|---|---|---|
OK | 200 | — | Config başarıyla getirildi. |
INVALID_TOKEN | 401 | Hayır | Token geçersiz/bilinmiyor, veya bağlı consentId ≠ path/gövde consentId → yeni AUTH (taze token). |
TOKEN_EXPIRED | 401 | Hayır | tokenExpiresIn dolmuş → yeni AUTH, ardından config'i yeniden çek. |
TOKEN_CONSUMED | 401 | Hayır | Token daha önce bir onay kaydı ile tüketilmiş → yeni AUTH. |
CONSENT_NOT_FOUND | 404 | Hayır | Bu consentId için yayımlanmış config yok → consentId doğrulanmalı; varsa bundled config fallback (§8). |
CONFIG_UNAVAILABLE | 503 | Evet | Config mevcut ama şu an servis edilemiyor → bundled config fallback, arka planda backoff ile dene. |
VALIDATION_ERROR | 400 | Hayır | Gövde şemayı karşılamıyor (örn. locale biçimi, zorunlu eksik alan) → detail[] alan hatalarını düzelt. |
RATE_LIMITED | 429 | Evet | Hız sınırı → Retry-After (sn) kadar bekle, yeniden dene. |
SERVER_ERROR | 500 | Evet | Sunucu iç hata → bundled config fallback, arka planda backoff ile dene. |
retryablesemantiği:false→ aynı istekle (aynı token) tekrar denemek işe yaramaz; yeni AUTH gerekir.true→ aynı istek (token hâlâ geçerliyse) daha sonra yeniden denenebilir.
8. Offline / Fallback Davranışı (KRİTİK)
Onay deneyimi sessizce bozulmamalı. Config getirilemese bile kullanıcı onay akışını yaşar.
| Senaryo | SDK davranışı |
|---|---|
INVALID_TOKEN / TOKEN_EXPIRED / TOKEN_CONSUMED | Yeni AUTH başlat → taze al → config'i yeniden çek. (Eski bir token ile retry boşuna 401 üretir.) |
SERVER_ERROR / CONFIG_UNAVAILABLE / RATE_LIMITED / timeout (15 sn) | Bundled (SDK'ya dahil) config ile devam et; arka planda exponential backoff ile sunucuyu dene. Bağlantı gelince + taze token ile config yenile. |
| Hiç önbellek yok ve çevrimdışı (ilk kurulum) | Bundled varsayılan config ile onay akışı çalışır; kullanıcı boş ekranda bırakılmaz. |
CONSENT_NOT_FOUND | consentId geçersiz/yayınlanmamış → bundled config varsa onunla devam, yoksa onay UI'ı zarifçe devre dışı (uygulama normal akışına döner). |
Kural: Hiçbir hatada onay deneyimi "boş ekran" veya "kilitlenmiş durum" üretmez. Okuma retry'ye toleranslı olduğu için backoff sınırlıdır; sonsuz döngü üretilmez.
9. Developer Notları
- GET /config = OKUMA yolu; yalnız bearer token (HMAC/nonce yok). Sunucu token'ı
X-Consent-Tokenheader'ından doğrular; replay koruması token'ın consentId-bağlılığı +tokenExpiresInpenceresi + oturum tüketimi ile sağlanır. SDK, ağ kesintisinden sonra güvenle retry yapabilir. (Yazma yolu olan POST_CONSENT ise HMAC+nonce ister.) - Token = oturum kimliği (one per AUTH), tek HTTP çağrısı DEĞİL. Bu adım tamamlanınca
tokenConsumed: falsedöner → aynı token ile POST_CONSENT'e güvenle geçilir. - Response
configalanı = tam config. SDK parse eder:behavior(dil/ATT/retrigger),theme,banner,manager.groups[](+consentKeys[]+items[]),detail,localization. Config değişikliğinde örnek de güncellenir. - Sunucu tüm dilleri döndürür; dil çözümlemesi SDK'da. Request
locale'i response'u daraltmaz; SDKbehavior.defaultLanguage+ kullanıcı tercihi +availableLanguagesile aktif dili seçer. Dil değiştirmek yeniden istek atmayı gerektirmez. - Akışı sırala: AUTH (token al) →
updateRequiredise bu adım (tam config, parse → UI kur) → kullanıcı karar verirse POST_CONSENT (aynı token ile) → responselocalState'ı önbelleğe yaz → döngü kapalı. consentKeysgrup seviyesindedir; etiket dağıtımı SDK'dadır. Config'dekigroups[].consentKeysve onay adımının döndürdüğü{[groupId]: state}haritası, SDK tarafında etiket key'lerine yayılır (02 adımında). Sunucu config'i ham olarak döndürür; çevirimi SDK sorumluluğudur.- Çapraz-doğrulama: Sunucu path
{consentId}↔ gövdeconsentId↔ token'ın bağlı consentId üçlüsünü karşılaştırır; uyumsuzluk401 INVALID_TOKENdöndürür. SDK üçünü de AUTH çıktısından/istekten doğru üretmelidir.
Bu doküman size yardımcı oldu mu?
Değerlendirmeniz, dokümanı geliştirmemize yardımcı olur.
Değerlendirme yapmak için giriş yapmalısınız.
Destek soruları ve yorumlar
Bu dokümanla ilgili soru sorabilir veya deneyiminizi paylaşabilirsiniz.