E-İmza API Entegrasyonu: REST + Webhook + 5 Dil SDK Tam Rehber (2026)
E-imza API entegrasyonu, modern SaaS’larda en yaygın talep edilen özelliklerden biri. CRM’inizdeki müşteriye, İK sisteminizdeki çalışana, e-ticaret platformunuzdaki alıcıya — kendi sisteminizden tek bir API isteğiyle dijital imza akışı başlatabilirsiniz. Bu rehber geliştiriciler için tüm detayları içerir.
Görsel: Modern REST API ile dijital imza entegrasyonu — kod örnekleriyle 1 saatte canlı
Neden API Entegrasyonu?
Dashboard’dan manuel sözleşme oluşturmak, küçük volume için OK. Ama:
- 100+ sözleşme/gün otomatik üretiliyor (e-ticaret checkout, İK işe alım) → manuel imkansız
- Kullanıcı kendi sisteminde kalmalı (örn: BambooHR’da işe alımı tamamlayınca otomatik sözleşme gitsin)
- Durum güncellemeleri real-time gerekli (CRM’de “müşteri imzaladı” işareti)
- Audit trail kendi DB’nizde tutulmalı (compliance + raporlama)
API entegrasyonu bu 4 problemi tek seferde çözer.
İmzala.org API Genel Bakış
| Özellik | Değer |
|---|---|
| Protokol | HTTPS + REST + JSON |
| Versiyon | v1 (stable, breaking change yok) |
| Authentication | X-API-Key header |
| Rate limit | 600 req/dakika (varsayılan) |
| Webhook | HMAC-SHA256 imzalı, 7-deneme retry |
| Idempotency | Idempotency-Key header desteği |
| SDK | Node.js, Python, PHP, Java, .NET |
| Sandbox | api-test.imzala.org |
| Production | api.imzala.org |
| Dokümantasyon | api-docs.imzala.org (OpenAPI 3.0) |
Adım 1: API Anahtarı Al
Dashboard → Ayarlar → API Anahtarları → “Yeni Anahtar”:
imz_a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
Önemli:
- Anahtar bir kere gösterilir — kaybederseniz iptal + yeniden üretim
- İzin granülaritesi:
demand.create,demand.read,template.read,webhook.manage— sadece gerekli olanları verin - Ortam ayrımı: Sandbox + Production ayrı anahtarlar — karıştırmayın
- Rotation: 90 günde bir yenilemenizi öneririz (compliance + güvenlik)
Görsel: REST API + JSON yanıt — geliştirici tipik workspace’i
Adım 2: İlk İstek — Sözleşme Oluştur
cURL Örneği
curl -X POST https://api.imzala.org/api/v1/demands \
-H "X-API-Key: imz_a1b2c3..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f7d2-batch-001" \
-d '{
"template_id": "tmpl_iskontrat_v3",
"signers": [
{
"name": "Mehmet Yılmaz",
"email": "[email protected]",
"phone": "+905551234567",
"fields": {
"tutar": 15000,
"baslangic_tarihi": "2026-06-01"
}
}
],
"send_via": ["email", "sms"],
"verification": "otp",
"language": "tr"
}'
Başarılı Yanıt (201 Created)
{
"id": "demand_8f7d2",
"status": "PENDING",
"signers": [
{
"id": "signer_a1b2",
"name": "Mehmet Yılmaz",
"status": "PENDING",
"sign_url": "https://e.imzala.org/imza/signer_a1b2",
"sent_at": "2026-05-29T14:00:00Z"
}
],
"created_at": "2026-05-29T14:00:00Z",
"expires_at": "2026-06-12T14:00:00Z"
}
Node.js SDK Örneği
import { Imzala } from '@imzala/sdk';
const client = new Imzala({ apiKey: process.env.IMZALA_API_KEY });
const demand = await client.demands.create({
templateId: 'tmpl_iskontrat_v3',
signers: [{
name: 'Mehmet Yılmaz',
email: '[email protected]',
phone: '+905551234567',
fields: { tutar: 15000, baslangic_tarihi: '2026-06-01' }
}],
sendVia: ['email', 'sms'],
verification: 'otp',
// SDK otomatik Idempotency-Key üretir
});
console.log('Sign URL:', demand.signers[0].signUrl);
Python SDK Örneği
from imzala import Imzala
client = Imzala(api_key=os.environ['IMZALA_API_KEY'])
demand = client.demands.create(
template_id='tmpl_iskontrat_v3',
signers=[{
'name': 'Mehmet Yılmaz',
'email': '[email protected]',
'phone': '+905551234567',
'fields': {'tutar': 15000, 'baslangic_tarihi': '2026-06-01'}
}],
send_via=['email', 'sms'],
verification='otp',
)
print('Sign URL:', demand.signers[0].sign_url)
Adım 3: Webhook ile Anlık Bildirimleri Yakala
API ile sözleşme oluşturduktan sonra polling YAPMAYIN — webhook ile sistem size bildirim atar.
Webhook Yapılandırma
Dashboard → Webhooks → “Yeni Endpoint”:
URL: https://your-domain.com/webhooks/imzala
Events: demand.signed, demand.declined, demand.expired, demand.viewed
Secret: whsec_a1b2c3d4... (HMAC için, kopyalayın)
Retry: Otomatik 7 deneme (1m → 5m → 15m → 1h → 6h → 24h → manual)
Webhook Payload Örneği
{
"event_id": "evt_x1y2z3",
"event_type": "demand.signed",
"timestamp": "2026-05-29T14:32:11Z",
"data": {
"demand_id": "demand_8f7d2",
"signer_id": "signer_a1b2",
"signer_email": "[email protected]",
"signed_at": "2026-05-29T14:32:11Z",
"all_parties_signed": true,
"pdf_url": "https://api.imzala.org/api/v1/demands/demand_8f7d2/pdf",
"audit_url": "https://api.imzala.org/api/v1/demands/demand_8f7d2/audit"
}
}
HMAC İmza Doğrulama (KRİTİK)
Webhook’unuz public URL — kötü niyetli istekler gelebilir. Her webhook’u doğrulayın:
Node.js
import crypto from 'crypto';
app.post('/webhooks/imzala', (req, res) => {
const signature = req.headers['x-imzala-signature'];
const body = req.rawBody; // BODY RAW olmalı, parse edilmeden ÖNCE
const expected = crypto
.createHmac('sha256', process.env.IMZALA_WEBHOOK_SECRET)
.update(body)
.digest('hex');
if (signature !== expected) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(body);
// Idempotency check — aynı event_id 2 kez gelebilir (retry)
if (await alreadyProcessed(event.event_id)) {
return res.status(200).send('Already processed');
}
await processEvent(event);
await markProcessed(event.event_id);
res.status(200).send('OK');
});
Python
import hmac
import hashlib
@app.route('/webhooks/imzala', methods=['POST'])
def webhook():
signature = request.headers.get('X-Imzala-Signature')
body = request.get_data() # raw body
expected = hmac.new(
os.environ['IMZALA_WEBHOOK_SECRET'].encode(),
body,
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(signature, expected):
return 'Invalid signature', 401
event = json.loads(body)
# Idempotency
if already_processed(event['event_id']):
return 'Already processed', 200
process_event(event)
mark_processed(event['event_id'])
return 'OK', 200
Önemli: 2xx Hızlı Dön
Webhook handler’ınızı hızlı dönmeli (< 3 saniye). Uzun işlem varsa:
- 2xx hemen dön (200 OK)
- İşi background queue’ya at (BullMQ, Celery, Sidekiq)
- Asenkron olarak işle
Aksi takdirde İmzala sistemi timeout sanır, retry yapar → duplicate işleme riski.
Görsel: Webhook ile gerçek zamanlı entegrasyon — kullanıcı imzalar imzalamaz sisteminize bildirim
Adım 4: Durum Sorgulama + PDF İndirme
Durum Sorgulama (GET)
curl https://api.imzala.org/api/v1/demands/demand_8f7d2 \
-H "X-API-Key: imz_..."
{
"id": "demand_8f7d2",
"status": "SIGNED",
"signers": [
{
"id": "signer_a1b2",
"status": "SIGNED",
"signed_at": "2026-05-29T14:32:11Z",
"sign_ip": "192.0.2.1",
"sign_device": "iPhone 14, Safari 17.4"
}
],
"completed_at": "2026-05-29T14:32:11Z",
"pdf_url": "https://api.imzala.org/api/v1/demands/demand_8f7d2/pdf"
}
İmzalanmış PDF İndirme
curl https://api.imzala.org/api/v1/demands/demand_8f7d2/pdf \
-H "X-API-Key: imz_..." \
-o "kontrat-mehmet-yilmaz.pdf"
PDF:
- ✅ TÜBİTAK Kamu SM zaman damgalı
- ✅ CMS/PAdES standardında mühürlü
- ✅ Adobe Reader yeşil tik
- ✅ Audit trail PDF içine gömülü
İdempotency — Duplicate’ı Engelle
Network gecikmesi, kullanıcı double click, retry logic — aynı isteği farkında olmadan iki kez göndermek olağan. Çözüm: Idempotency-Key.
curl -X POST https://api.imzala.org/api/v1/demands \
-H "X-API-Key: imz_..." \
-H "Idempotency-Key: order_12345_signing_v1" \
-d '{ ... }'
Sistem bu key’i 24 saat hatırlar. Aynı key ile ikinci istek geldiğinde:
- ✅ Aynı yanıtı döner (yeniden oluşturmaz)
- ✅ HTTP status: 200 (yeni 201 değil)
- ✅ Header’da
Idempotency-Replayed: true
Önerilen: Her POST’da unique idempotency key gönderin (UUID v4 veya ${order_id}_${operation_v}).
Rate Limit Yönetimi
Sistem dakikada 600 istek kabul eder. Aşıldığında:
HTTP/2 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1717000800
Best Practice
async function withRateLimitRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (err.status === 429 && i < maxRetries - 1) {
const retryAfter = parseInt(err.headers['retry-after'], 10) || 5;
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
throw err;
}
}
}
Volume yüksek? Bulk endpoint kullanın:
POST /api/v1/demands/bulk
# 1 istek = 100 sözleşme
# Rate limit pratikte 60.000 sözleşme/dakika eşdeğer
Görsel: Backend altyapı — Almanya Hetzner veri merkezinde, KVKK + GDPR çift uyum
Hata Yönetimi
Tüm hatalar standart JSON format:
{
"error": "INVALID_PHONE",
"message": "Phone number is not valid E.164",
"details": {
"field": "signers[0].phone",
"value": "5551234567",
"expected": "+905551234567"
},
"request_id": "req_8f7d2"
}
Önemli Hata Kodları
| HTTP | Code | Anlamı | Çözüm |
|---|---|---|---|
| 400 | INVALID_REQUEST | JSON format hatalı | Body’yi kontrol et |
| 400 | INVALID_PHONE | E.164 değil | +90 prefix ekle |
| 400 | INVALID_EMAIL | Email format hatalı | Doğrula |
| 401 | UNAUTHENTICATED | API key yok/yanlış | X-API-Key header |
| 403 | PERMISSION_DENIED | Anahtarın izni yok | Dashboard’dan izin ver |
| 404 | TEMPLATE_NOT_FOUND | Template ID yanlış | ID’yi doğrula |
| 422 | BUSINESS_RULE_VIOLATION | İş kuralı (örn: imzacı sayısı limit aşımı) | Plan upgrade veya değiştir |
| 429 | RATE_LIMITED | Rate limit aşıldı | Retry-After bekle |
| 500 | INTERNAL_ERROR | Sunucu hatası | Request_id ile destek |
50+ hata kodu tam kataloğu api-docs.imzala.org/errors.
Best Practice: Sentry Entegrasyonu
try {
await client.demands.create({...});
} catch (err) {
if (err.code === 'RATE_LIMITED') {
// Retry logic
} else if (err.code === 'VALIDATION') {
// User-facing error
return res.status(400).json({ error: err.message });
} else {
Sentry.captureException(err, {
tags: { api: 'imzala', operation: 'create_demand' },
extra: { requestId: err.request_id },
});
throw err;
}
}
Geliştirici Workspace — 5 Dil SDK
| Dil | Paket | Install |
|---|---|---|
| Node.js | @imzala/sdk | npm install @imzala/sdk |
| Python | imzala-sdk | pip install imzala-sdk |
| PHP | imzala/sdk | composer require imzala/sdk |
| Java | org.imzala:sdk | Maven/Gradle |
| .NET | Imzala.Sdk | dotnet add package Imzala.Sdk |
Her SDK:
- ✅ Auto-pagination
- ✅ Retry logic (exponential backoff)
- ✅ Webhook signature verification
- ✅ TypeScript types (Node.js)
- ✅ Async/await native
Görsel: Modern geliştirici workspace’i — İmzala.org API entegrasyonu
Tipik Use Case Örnekleri
1. E-Ticaret Checkout → Mesafeli Satış Sözleşmesi
// Checkout tamamlandığında
async function onCheckoutComplete(order) {
const demand = await imzala.demands.create({
templateId: 'tmpl_mesafeli_satis_v2',
signers: [{
name: order.customer.fullName,
email: order.customer.email,
phone: order.customer.phone,
fields: {
siparis_no: order.id,
toplam_tutar: order.total,
cayma_son_tarih: addDays(new Date(), 14),
}
}],
sendVia: ['email'],
verification: 'otp',
});
await db.orders.update(order.id, {
signing_demand_id: demand.id,
status: 'AWAITING_SIGNATURE',
});
}
// Webhook ile imza tamamlanınca
app.post('/webhooks/imzala', verifySignature, async (req, res) => {
if (req.body.event_type === 'demand.signed') {
await db.orders.update({
signing_demand_id: req.body.data.demand_id,
}, { status: 'PROCESSING' });
await sendEmail(order.customer.email, 'Siparişiniz hazırlanıyor');
}
res.send('OK');
});
2. İK İşe Alım → İş Sözleşmesi
def on_offer_accepted(offer):
demand = imzala.demands.create(
template_id='tmpl_is_sozlesmesi',
signers=[{
'name': offer.candidate_name,
'email': offer.candidate_email,
'fields': {
'pozisyon': offer.position,
'maas': offer.salary,
'baslangic_tarihi': offer.start_date.isoformat(),
}
}],
send_via=['email', 'sms'],
verification='otp',
)
db.offers.update(offer.id, signing_demand_id=demand.id)
# Webhook
@app.post('/webhooks/imzala')
def webhook(request):
verify_signature(request)
event = request.json
if event['event_type'] == 'demand.signed':
offer = db.offers.get_by_demand(event['data']['demand_id'])
bamboohr.create_employee_from_offer(offer)
slack.post(f"🎉 {offer.candidate_name} işe başlıyor!")
return 'OK', 200
3. Toplu İşlem (Yıllık Yenileme)
# 500 müşteriye aynı anda gönder
POST /api/v1/demands/bulk
Content-Type: multipart/form-data
template_id: tmpl_yillik_yenileme
csv_file: @customers_2026.csv
send_via: email,sms
verification: otp
# Yanıt: batch_id, her demand'in URL'i, hata listesi
Production Checklist
Production’a geçmeden önce:
- Webhook URL HTTPS (HTTP kabul edilmez)
- HMAC signature verification implement edildi + test edildi
- Idempotency key her POST’da gönderiliyor
- Rate limit retry logic ile retry-After respect ediliyor
- Sentry/DataDog monitoring aktif (api errors + webhook delivery)
- Webhook timeout < 3 saniye + background queue
- API key rotation runbook hazır
- Sandbox → Production env variables ayrı (karıştırılmıyor)
- Audit log kendi DB’nizde tutuluyor (sözleşme ID + status + zaman)
- KVKK aydınlatma metni “X verilerinizi İmzala.org API’si üzerinden işliyoruz” beyanı içeriyor
Sık Sorulan Sorular
İmzala.org API hangi formatta?
Modern REST API: HTTPS + JSON + X-API-Key header (Bearer değil). Tüm endpoint’ler /api/v1/* altında. Yanıtlar UTF-8 JSON, hata kodları HTTP standardı (200/400/401/403/404/422/429/500). Rate limit: dakikada 600 istek (varsayılan, kurumsal planda artırılabilir).
API kimlik doğrulaması nasıl?
X-API-Key header. Format: ‘imz_’ + 64 hex karakter (örn: imz_a1b2c3…). Her isteğe ekleyin: ‘X-API-Key: imz_…’. Anahtar dashboard’dan üretilir/iptal edilir, izinler granular (sadece sözleşme oluştur / sadece okuma / webhook yönet).
Webhook güvenliği nasıl sağlanır?
Her webhook isteğinde X-Imzala-Signature header’ında HMAC-SHA256(webhook_secret, request_body) değeri gelir. Sizin tarafınızda aynı hesaplamayı yapıp karşılaştırırsanız sahte istekleri reddedersiniz. Ayrıca event_id ile idempotency check yapın (aynı event 2 kez gelebilir — retry/network durumu).
Webhook ulaşmıyor — ne yapmalı?
Dashboard → Webhooks → Logs sekmesinde her teslim denemesini görebilirsiniz: HTTP status, latency, body. Eğer endpoint’iniz 2xx döndürmüyorsa sistem exponential retry uygular (1m, 5m, 15m, 1h, 6h, 24h — 7 deneme). 7 başarısız sonrası webhook ‘failed’ işaretlenir, dashboard’dan manuel retry edebilirsiniz.
Sandbox/test ortamı var mı?
Evet. Sandbox URL: api-test.imzala.org. Sandbox API anahtarınızla buraya istek atın, gerçek SMS/e-posta gönderilmez (sadece dashboard’da görünür), gerçek TÜBİTAK zaman damgası eklenmez. Geliştirme + entegrasyon testi için ideal. Production: api.imzala.org.
İdempotency key ne işe yarar?
Aynı isteği iki kez atarsanız (network retry, kullanıcı double click) iki sözleşme oluşturmamak için. Her POST isteğinde Idempotency-Key header’ı (kendi ürettiğiniz UUID veya unique string) gönderin. Sistem bu key’le 24 saat boyunca aynı yanıtı döner — duplicate sözleşme oluşmaz.
API rate limit nedir?
Varsayılan: dakikada 600 istek (10/saniye ortalama). Üzerine çıkarsa 429 Too Many Requests + Retry-After header (saniye olarak ne kadar beklemeniz gerektiği). Ücretsiz planda daha düşük (60/dk), kurumsal planda artırılabilir. Toplu işlemler için bulk endpoint (1 istek = 100 sözleşme) tercih edin.
Yanıtlar ne kadar hızlı?
Tipik latency P50 80-150ms, P95 200-400ms. Sözleşme oluşturma (POST /demands) en yüksek (şablon parse + PDF rendering): P50 ~250ms. Durum sorgulama (GET) P50 ~50ms. İmzalanan PDF indirme (GET /pdf) belge boyutuna bağlı, ortalama 500ms-2s.
Hata yönetimi nasıl?
Tüm hatalar standart JSON formatında: { error: 'INVALID_PHONE', message: 'Phone number is not valid E.164', details: { field: 'signers[0].phone' } }. HTTP status: 400 (validation), 401 (auth), 403 (permission), 404 (not found), 422 (business rule), 429 (rate limit), 500 (server). 50+ hata kodu için kataloğumuz dökümanlarda.
Hangi SDK'lar var?
Node.js (npm: @imzala/sdk), Python (pip: imzala-sdk), PHP (composer: imzala/sdk), Java (Maven: org.imzala:sdk), .NET (NuGet: Imzala.Sdk). Hepsi auto-pagination, retry logic, webhook signature verification built-in. iOS Swift + Android Kotlin SDK yol haritamızda.
API hangi dilde dökümante edilmiş?
api-docs.imzala.org adresinde Türkçe + İngilizce. OpenAPI 3.0 spec (Swagger UI), her endpoint için 5 dilde örnek kod, response/request shape, hata senaryoları. Postman collection indirilebilir. Webhook event payload örnekleri JSON Schema ile tanımlı.
İK / CRM yazılımıma direkt entegrasyon var mı?
Direkt ‘plug & play’ entegrasyon yok ama webhook + REST API ile çoğu sisteme 1-3 günlük entegrasyon yapılır. BambooHR, Personio, Salesforce, HubSpot, Shopify gibi popüler sistemler için örnek kodlar dökümanlarda. Zapier / Make.com entegrasyonu yol haritamızda.
Sonuç
İmzala.org API, dijital imzayı kendi sisteminizin doğal bir parçası haline getirir. Modern REST + JSON + 5 dil SDK + güvenli webhook ile 1 saatte canlıya çıkabilirsiniz. Sandbox ortamında ücretsiz test edin, hazır olduğunuzda tek environment variable değişikliğiyle production’a geçin.
İmzala.org API hızlı özet:
- 📡 REST + JSON + HTTPS (standart, basit)
- 🔐 X-API-Key + HMAC webhook (güvenli)
- 🔄 Idempotency + Retry + Bulk (production-ready)
- 📚 5 dil SDK + OpenAPI 3.0 dokümantasyon (geliştirici dostu)
- 🌐 Sandbox + Production environment ayrımı (güvenli geliştirme)
- ⚡ P50 latency < 150ms, %99.9 SLA (hızlı + güvenilir)
İlgili Rehberler: