İçeriğe geç

REST API (Tool API ve Sunucudan Sunucuya)

Tarayıcı SDK’sı Tool API ile konuşur. Aynı API’yi kendi backend’inizden de çağırabilirsiniz — kendi arayüzünüzde alınan onayları kaydetmek, tek kullanımlık onay token’ları üretmek veya kayıtları sorgulayıp doğrulamak için.

Temel URL: https://system.hashentry.com

MetotYolAmaçKimlik doğrulama
GET/tool/v1/configBanner yapılandırması, bağlı dokümanlar, algılanan bölgeAPI anahtarı (read)
GET/tool/v1/documents/{slug}/activeTek bir dokümanın, içeriği dahil aktif sürümüAPI anahtarı (read)
GET/tool/v1/documents/activeSiteye bağlı aktif dokümanlarAPI anahtarı (read)
POST/tool/v1/consentsTek bir onay kaydeder (tarayıcı / mobil SDK rotası)API anahtarı (write) + imza
POST/tool/v1/consents/batch100’e kadar onay kaydederAPI anahtarı (write) + imza
POST/tool/v1/s2s/consentsBackend’inizden tek bir onay kaydederAPI anahtarı (write) + JWT + imza
POST/tool/v1/s2s/consents/batchBackend’inizden 100’e kadar onay kaydederAPI anahtarı (write) + JWT + imza
POST/tool/v1/s2s/approval-tokensTek kullanımlık bir doküman onay token’ı üretirAPI anahtarı (write) + JWT + imza
GET/tool/v1/consents/statusTek bir ziyaretçinin güncel onaylarıAPI anahtarı (read)
GET/tool/v1/consents/verify/{id}Tek bir kaydın bütünlük kontrolüAPI anahtarı (read)
GET POST/api/v1/public/consents/verifyHerkese açık bütünlük kontrolü (anahtarsız)yok

Her Tool API isteği sitenin anahtarını taşır:

X-API-Key: he_live_…

Bir anahtarın bir kapsamı (scope) vardır: read, GET endpoint’lerine izin verir; write buna ek olarak POST isteklerine izin verir. Site panelde doğrulanmış olmalıdır. Sitenin izin verilen origin’ler listesi varsa, diğer origin’lerden gelen tarayıcı istekleri reddedilir; IP izin listesi varsa, diğer adreslerden gelen istekler reddedilir.

X-Signature: <hex HMAC-SHA256>
X-Timestamp: <Unix time in seconds>
X-Nonce: <unique value per request>
body_hash = SHA-256(raw request body) (lowercase hex)
canonical = METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + NONCE + "\n" + body_hash
signature = HMAC-SHA256(key = API key, message = canonical) (lowercase hex)
  • METHOD büyük harflidir. PATH, /tool/v1 dahil, sorgu dizesi (query string) hariç istek yoludur; örn. /tool/v1/s2s/consents.
  • Gövde hash’i, gönderdiğiniz baytların tam olarak kendisi üzerinden hesaplanır. JSON’u bir kez serileştirin ve aynı dizeyi gönderin.
  • X-Timestamp, sunucu saatinin ±300 saniye aralığında olmalıdır.
  • X-Nonce, A–Z a–z 0–9 . _ : - karakterlerinden oluşan 8–128 karakterdir (bir UUID uygundur) ve site başına yalnızca bir kez kullanılabilir; tekrarı NONCE_REPLAYED ile reddedilir.

Adım adım örnek (SDK ile API’nin ortak test vektörü):

API key : he_live_0123456789abcdef0123456789abcdef
Method : POST
Path : /tool/v1/consents
Timestamp : 1760000000
Nonce : 3f2b8c1e-5a47-4d0e-9b6a-7c1d2e3f4a5b
Body : {"consent_type":"cookie","decision":"accepted","language":"tr","idempotency_key":"9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d","metadata":{"note":"çerez ✓"}}
body_hash : 93316d8d6adb505a19668f4022e4e33b12aed9c0c4bb97d205b5064257090d34
canonical : POST\n/tool/v1/consents\n1760000000\n3f2b8c1e-5a47-4d0e-9b6a-7c1d2e3f4a5b\n93316d8d6adb505a19668f4022e4e33b12aed9c0c4bb97d205b5064257090d34
signature : e108683927badf35c36d5f467f63a9704c131d0102f14b06af7ed3046d44a8be

(\n, tek bir satır besleme (line feed) karakterini ifade eder; gövde UTF-8’dir.) Uygulamanız bu girdiler için bu imzayı üretiyorsa doğrudur.

Node.js
const crypto = require('crypto');
function sign(apiKey, method, path, body) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomUUID();
const bodyHash = crypto.createHash('sha256').update(body, 'utf8').digest('hex');
const canonical = [method.toUpperCase(), path, timestamp, nonce, bodyHash].join('\n');
const signature = crypto.createHmac('sha256', apiKey).update(canonical, 'utf8').digest('hex');
return { 'X-Signature': signature, 'X-Timestamp': timestamp, 'X-Nonce': nonce };
}
const body = JSON.stringify({ consent_type: 'document_approval', decision: 'accepted', /* … */ });
const headers = {
'Content-Type': 'application/json',
'X-API-Key': apiKey,
Authorization: `Bearer ${jwt}`, // yalnızca S2S rotaları
...sign(apiKey, 'POST', '/tool/v1/s2s/consents', body),
};

İmza, isteğin API anahtarıyla yapıldığını ve tekrar oynatılmadığını (replay) kanıtlar. Tarayıcı SDK’sı, sayfa kaynağında görünür olan aynı anahtarı kullandığından, imza tek başına bir isteğin backend’inizden geldiğini kanıtlamaz — S2S rotaları bunun içindir.

Sunucudan sunucuya rotalar (/tool/v1/s2s/…)

Section titled “Sunucudan sunucuya rotalar (/tool/v1/s2s/…)”

S2S istekleri üç şey gerektirir: write kapsamlı bir API anahtarı, istek imzası ve api_user rolüne sahip bir kullanıcının JWT’si:

  1. Panelde api_user rolüyle bir ekip üyesi davet edin. Bu rol yalnızca S2S API’yi kullanabilir; panele giriş yapamaz.
  2. JWT almak için POST /api/v1/auth/login ile oturum açın; POST /api/v1/auth/refresh ile yenileyin.
  3. Authorization: Bearer <jwt> başlığını X-API-Key ve imza başlıklarıyla birlikte gönderin. Kullanıcı, sitenin sahibi olan tenant’a ait olmalıdır.

Yalnızca S2S istekleri ip_address, user_agent, otp_verified ve otp_reference alanlarını ayarlayabilir. Tarayıcı rotasında IP adresi ve user agent her zaman bağlantıdan alınır ve OTP alanları yok sayılır.


POST /tool/v1/consents (veya /tool/v1/s2s/consents)

{
"consent_type": "cookie",
"decision": "partial",
"document_version_id": "0190a1b2-…",
"language": "en",
"categories": { "necessary": true, "analytics": true, "marketing": false },
"idempotency_key": "9a1c2b3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
"visitor_id": "user-4711",
"visitor_region": "DE",
"compliance_framework": "gdpr",
"metadata": { "order_id": "ORD-54321" }
}
AlanKurallar
consent_typeZorunlu. 50 karaktere kadar (A–Z a–z 0–9 _ - .). Kullanımda olanlar: cookie, document_approval, do_not_sell_opt_out.
decisionZorunlu. accepted, rejected, partial veya withdrawn.
document_version_idSiteye bağlı bir dokümanın aktif bir sürümünün UUID’si. Bu alan olmadan — veya aktif olmayan bir sürümle — istek 409 CONFIG_OUTDATED ile reddedilir. Bir çerez onayı, sitenin cookie_policy dokümanına referans verir.
languageVerilmişse, o sürümün dili olmalıdır.
categoriesKategori anahtarı → boolean biçiminde nesne. Yalnızca banner yapılandırmasında tanımlı kategoriler saklanır.
idempotency_key8–64 karakter (A–Z a–z 0–9 . _ : -). Aşağıya bakın.
visitor_idKişi için sizin referansınız, 100 karaktere kadar.
visitor_region, visitor_country10 / 2 karaktere kadar.
compliance_frameworkkvkk, gdpr, uk_gdpr, ccpa, lgpd, popia, pipeda, pipl, pipa veya none.
source20 karaktere kadar, örn. client, server.
metadata, extra_fieldsHer biri en fazla 30 anahtar ve yaklaşık 16 KB olan nesneler.
approval_tokenBir document_approval için tek kullanımlık token (aşağıya bakın).
İmza / özel doküman alanlarısignature_image, signature_mime_type, signer_name, signer_email, signer_phone, signer_id_number, declaration_text, drawing_duration_ms, stroke_count, strokes_data, input_type, screen_resolution, custom_document_content, custom_document_mime_type — tümü üst düzeydedir. Bkz. Doküman Onayı ve İmza.
ip_address, user_agent, otp_verified, otp_referenceYalnızca S2S.

document_version_id değerini GET /tool/v1/config?language=en (data.documents[].version.id) veya GET /tool/v1/documents/{slug}/active?language=en üzerinden alın.

{
"message": "…",
"data": {
"consent_token": "ct_…",
"proof_hash": "…64 hex characters…",
"created_at": "2026-10-10T10:00:00+00:00",
"duplicate": false
}
}

202, isteğin tüm kontrollerden geçtiği ve kaydın yazılmak üzere kabul edildiği anlamına gelir. Token, kanıt hash’i ve zaman damgası bu noktada kesindir; ancak satır bir arka plan worker’ı tarafından yazılır, bu nedenle status ve verify kısa bir an için kaydı bulamayabilir.

Kullanıcı eylemi başına bir anahtar gönderin ve o eylemin her yeniden denemesinde aynı anahtarı kullanın. Aynı anahtarla tekrarlanan bir istek ikinci bir kayıt oluşturmaz ve kota tüketmez; özgün yanıtı "duplicate": true ile döndürür. Anahtarlar 24 saat boyunca hatırlanır. Tarayıcı SDK’sı karar başına bir UUID üretir ve bunu ilk deneme, istemci yeniden denemeleri ve çevrimdışı kuyruğundan yapılan yeniden gönderimler için kullanır.

{ "consents": [ { … }, … ] } ile POST /tool/v1/consents/batch (1–100 öğe, yukarıdakiyle aynı alanlar).

{
"data": {
"accepted": 2,
"rejected": 1,
"results": [
{ "index": 0, "status": "accepted", "consent_token": "ct_…", "proof_hash": "…", "created_at": "…", "duplicate": false },
{ "index": 1, "status": "accepted", "consent_token": "ct_…", "proof_hash": "…", "created_at": "…", "duplicate": true },
{ "index": 2, "status": "rejected", "error": "…", "error_code": "CONSENT_LIMIT_EXCEEDED", "code": 429 }
]
}
}

Toplu istek işlendiğinde durum kodu 202 olur; results içindeki her girdiyi kontrol edin. Doğrulama hataları ve bilinmeyen ya da aktif olmayan bir doküman sürümü içeren bir öğe, toplu isteğin tamamını reddettirir (422 / 409).


POST /tool/v1/s2s/approval-tokens — yalnızca S2S.

{
"document_slug": "service-contract",
"subject": "user-4711",
"signer_name": "Jane Doe",
"signer_email": "[email protected]",
"expires_in": 600
}
AlanKurallar
document_slug / document_version_idEn az biri. Sürüm kimliği verildiğinde token yalnızca o sürüm için geçerlidir.
subjectZorunlu. Kişi için sizin referansınız (en fazla 100 karakter); kaydın visitor_id değeri olarak saklanır.
signer_name, signer_email, signer_phone, signer_id_numberİsteğe bağlı. Kefil olduğunuz kimlik bilgileri.
otp_verified, otp_referenceİsteğe bağlı. Gerçekleştirdiğiniz bir OTP kontrolünü beyan eder.
custom_document_hashİsteğe bağlı. Sisteminizin ürettiği bir dokümanın SHA-256 değeri (hex); bu durumda onay tam olarak o içeriği taşımalıdır.
expires_inSaniye, 30–3600. Varsayılan 600.

Yanıt 201:

{
"data": {
"approval_token": "hat_…",
"approval_token_id": "atk_…",
"expires_in": 600,
"expires_at": "2026-10-10T10:10:00+00:00",
"document_id": "…",
"document_slug": "service-contract",
"document_version_id": null
}
}

approval_token değerini sayfaya verin ve SDK’ya iletin (approvalToken) veya bir document_approval onayının üst düzey approval_token alanı olarak gönderin. Sunucu token’ı bir kez tüketir, kimliği token’dan alır ve gizli olmayan approval_token_id ile birlikte identity_assurance: tenant_attested değerini kaydeder. Başka bir nedenle (hız sınırı, kota) reddedilen bir istek token’ı tüketmez. HashEntry, token’ın yalnızca hash’ini saklar.


GET /tool/v1/consents/status?visitor_id=…

Section titled “GET /tool/v1/consents/status?visitor_id=…”

Tek bir visitor_id değerine ait, süresi dolmamış en fazla 20 onayı, en yenisi başta olacak şekilde döndürür. İsteğe bağlı filtreler: consent_type, document_slug, document_version_id.

{id}; bir onay UUID’si, bir consent_token (ct_…) veya bir proof_hash değeridir.

{
"valid": true,
"data": {
"consent_type": "cookie",
"decision": "accepted",
"proof_hash": "…",
"hash_version": 2,
"hash_valid": true,
"merkle_valid": null,
"is_anonymized": false,
"is_tsa_stamped": false,
"created_at": "2026-10-10T10:00:00+00:00"
}
}

Bu yanıtın ne anlama geldiği — ve ne anlama gelmediği:

  • valid: true şu anlama gelir: kayıt sizin tenant’ınıza aittir, HashEntry kanıt hash’ini saklanan kayıttan tenant’ınızın gizli anahtarıyla yeniden hesaplamış ve hash eşleşmiştir; ayrıca — kayıt bir Merkle grubunun (batch) parçasıysa — dahil edilme kanıtı doğrudur. Bir satırın var olması yeterli değildir.
  • Kaydın Merkle kanıtı yoksa merkle_valid değeri null olur.
  • is_tsa_stamped, kayıt için (doğrudan veya Merkle grubu üzerinden) bir zaman damgası token’ının var olduğunu söyler. Token’ın imzasının bu çağrıda doğrulandığını söylemez.
  • Bu, HashEntry’nin HashEntry verisi üzerinde yaptığı bir kontroldür. Sunucunun yanıtına güvenmeden doğrulamak için bir delil paketi dışa aktarın ve kendiniz doğrulayın: Delilleri çevrimdışı doğrulama.
  • Bilinmeyen bir kimlik, "valid": false ve code: "CONSENT_NOT_FOUND" ile 404 döndürür.

API anahtarı yoktur; hız sınırı uygulanır. Parametreler: token (bir ct_… token’ı veya SDK’nın _he_consent çerezinin değeri), proof_hash veya id. Kararı, kategorileri, site alan adını, zaman damgalarını, hash durumunu ve zaman damgası bilgisini döndürür; IP adresini, user agent’ı veya ziyaretçi kimliğini hiçbir zaman döndürmez.

  • Var olan bir kayıt: yukarıda açıklandığı şekilde valid değeriyle 200.
  • Bir sunucu kaydıyla eşleştirilemeyen bir tarayıcı çerezi değeri: "valid": false, "source": "client_token", "server_record_found": false ve çözülmüş çerez alanlarıyla 200. Çerez imzalı değildir; bu nedenle tek başına hiçbir zaman geçerli olarak bildirilmez.
  • Hiçbir şey bulunamadığında: "valid": false ile 404. Tanımlayıcı verilmediğinde: 422.

Hata yanıtları JSON’dur ve code alanında kararlı bir makine kodu taşır (ayrıca error_code ve error.code; bazı kimlik doğrulama hataları yalnızca error.code kullanır).

HTTPKodAnlamı
401MISSING_API_KEY, INVALID_API_KEYAPI anahtarı yok veya bilinmiyor.
401MISSING_SIGNATURE_HEADERS, TIMESTAMP_EXPIRED, INVALID_SIGNATURE, INVALID_NONCE, NONCE_REPLAYEDİstek imzası sorunları.
401MISSING_BEARER_TOKEN, INVALID_BEARER_TOKENS2S: JWT eksik veya geçersiz.
403SITE_NOT_VERIFIEDSiteyi panelde doğrulayın.
403ORIGIN_NOT_ALLOWED, IP_NOT_ALLOWEDSitenin izin listesinde değil.
403INSUFFICIENT_ROLE, TENANT_MISMATCHS2S: kullanıcı bu tenant’ın bir api_user kullanıcısı değil.
403—API anahtarının kapsamı bu metoda izin vermiyor.
404DOCUMENT_NOT_FOUND, VERSION_NOT_FOUND, CONSENT_NOT_FOUND
409CONFIG_OUTDATEDdocument_version_id eksik, aktif değil, dili yanlış veya sunucunun yapılandırma önbelleği soğuk. /tool/v1/config yanıtını yeniden okuyun; yalnızca sürüm hâlâ aktif sürümse yeniden gönderin.
422VALIDATION_ERRORAlan hataları errors içindedir.
422APPROVAL_TOKEN_REQUIRED, APPROVAL_TOKEN_INVALID, APPROVAL_TOKEN_CONFLICTBkz. tek kullanımlık onay token’ları.
422INVALID_CATEGORIES, METADATA_TOO_MANY_KEYS, METADATA_TOO_LARGE, EXTRA_FIELDS_TOO_MANY_KEYS, EXTRA_FIELD_NAME_TOO_LONG, EXTRA_FIELDS_TOO_LARGE, STROKES_DATA_TOO_LARGE, INVALID_SIGNATURE_IMAGE, SIGNATURE_IMAGE_TOO_LARGE, INVALID_CUSTOM_DOCUMENT, UNSUPPORTED_CUSTOM_DOCUMENT_TYPE, CUSTOM_DOCUMENT_TOO_LARGEİstek gövdesi (payload) sınırları.
429RATE_LIMIT_EXCEEDEDPlana göre hız sınırı. Bkz. Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining.
429CONSENT_LIMIT_EXCEEDED, NO_CONSENT_SUBSCRIPTIONPlanın onay kotası tükendi / aktif bir plan yok.
429TOO_MANY_INVALID_API_KEYSTek bir IP adresinden geçersiz anahtarlarla çok fazla istek.
503QUEUE_OVERLOADED, ADMISSION_UNAVAILABLE, API_KEY_LOOKUP_UNAVAILABLEGeçici. Retry-After süresinden sonra aynı idempotency_key ile yeniden deneyin.

408, 425, 429 ve 5xx yanıtlarını aynı gövde ve aynı idempotency_key ile (ve yeni bir zaman damgası, nonce ve imza ile) yeniden deneyin. Diğer 4xx yanıtlarını değiştirmeden yeniden denemeyin.