Examples
cURL, Node.js, Python, PHP ve Go için kopyala-yapıştır hazır snippet'lar. Tüm örnekler TD_API_KEY environment variable'ından okur — repo'ya gömmeyin.
Müşteri listesi (pagination)
İlk sayfayı çek, sonraki cursor varsa devam et.
curl -s 'https://teknikdanisman.net/api/v1/customers.php?limit=25' \
-H 'Authorization: Bearer tdk_...' | jq
const res = await fetch('https://teknikdanisman.net/api/v1/customers.php?limit=25', {
headers: { Authorization: `Bearer ${process.env.TD_API_KEY}` },
});
const { data, has_more, next_cursor } = await res.json();
console.log(`${data.length} müşteri çekildi, devamı: ${has_more ? next_cursor : 'yok'}`);
import os, requests
r = requests.get(
'https://teknikdanisman.net/api/v1/customers.php',
params={'limit': 25},
headers={'Authorization': f'Bearer {os.environ["TD_API_KEY"]}'},
)
r.raise_for_status()
body = r.json()
print(f"{len(body['data'])} müşteri, devamı: {body.get('next_cursor')}")
$ch = curl_init('https://teknikdanisman.net/api/v1/customers.php?limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('TD_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
echo count($body['data']) . " müşteri çekildi\n";
req, _ := http.NewRequest("GET", "https://teknikdanisman.net/api/v1/customers.php?limit=25", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("TD_API_KEY"))
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var body struct {
Data []map[string]any `json:"data"`
HasMore bool `json:"has_more"`
NextCursor *int `json:"next_cursor"`
}
json.NewDecoder(resp.Body).Decode(&body)
fmt.Printf("%d müşteri\n", len(body.Data))
Yeni personel oluştur
Idempotency-Key ile network retry güvenli POST.
curl -s -X POST 'https://teknikdanisman.net/api/v1/employees.php' \
-H 'Authorization: Bearer tdk_...' \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customer_id": 12,
"name": "Ayşe Yılmaz",
"role": "Muhasebe",
"email": "ayse@firma.com",
"hire_date": "2026-06-01"
}' | jq
import { randomUUID } from 'node:crypto';
const res = await fetch('https://teknikdanisman.net/api/v1/employees.php', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TD_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': randomUUID(),
},
body: JSON.stringify({
customer_id: 12,
name: 'Ayşe Yılmaz',
role: 'Muhasebe',
email: 'ayse@firma.com',
hire_date: '2026-06-01',
}),
});
if (res.status === 422) {
const { errors } = await res.json();
console.error('Validation hataları:', errors);
} else {
console.log('Oluştu:', await res.json());
}
import os, uuid, requests
r = requests.post(
'https://teknikdanisman.net/api/v1/employees.php',
headers={
'Authorization': f'Bearer {os.environ["TD_API_KEY"]}',
'Idempotency-Key': str(uuid.uuid4()),
},
json={
'customer_id': 12,
'name': 'Ayşe Yılmaz',
'role': 'Muhasebe',
'email': 'ayse@firma.com',
'hire_date': '2026-06-01',
},
timeout=10,
)
if r.status_code == 422:
print('Validation hataları:', r.json()['errors'])
else:
r.raise_for_status()
print('Oluştu:', r.json())
$payload = [
'customer_id' => 12,
'name' => 'Ayşe Yılmaz',
'role' => 'Muhasebe',
'email' => 'ayse@firma.com',
'hire_date' => '2026-06-01',
];
$ch = curl_init('https://teknikdanisman.net/api/v1/employees.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TD_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$body = json_decode($res, true);
if ($code === 422) print_r($body['errors']); else print_r($body);
payload := map[string]any{
"customer_id": 12,
"name": "Ayşe Yılmaz",
"role": "Muhasebe",
"email": "ayse@firma.com",
"hire_date": "2026-06-01",
}
b, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://teknikdanisman.net/api/v1/employees.php", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer "+os.Getenv("TD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.New().String())
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
Servis veya lisans yenile (+1 yıl)
Domain/hosting/SSL servisi ya da yazılım lisansının yenileme tarihini ileri al.
curl -s -X POST 'https://teknikdanisman.net/api/v1/renew.php' \
-H 'Authorization: Bearer tdk_...' \
-H 'Content-Type: application/json' \
-d '{"resource":"service","id":42}' | jq
const res = await fetch('https://teknikdanisman.net/api/v1/renew.php', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TD_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ resource: 'service', id: 42 }),
});
const { data } = await res.json();
console.log(`Güncellenen kolonlar: ${data.updated_columns.join(', ')}`);
import os, requests
r = requests.post(
'https://teknikdanisman.net/api/v1/renew.php',
headers={'Authorization': f'Bearer {os.environ["TD_API_KEY"]}'},
json={'resource': 'service', 'id': 42},
)
print(r.json()['data']['updated_columns'])
$ch = curl_init('https://teknikdanisman.net/api/v1/renew.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['resource' => 'service', 'id' => 42]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TD_API_KEY'),
'Content-Type: application/json',
],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($body['data']);
b, _ := json.Marshal(map[string]any{"resource": "service", "id": 42})
req, _ := http.NewRequest("POST", "https://teknikdanisman.net/api/v1/renew.php", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer "+os.Getenv("TD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
Webhook imza doğrulama (receiver)
Express/Flask/Slim handler — HMAC-SHA256 ile gelen X-TD-Signature'ı timing-safe karşılaştırır.
# Bu sizin receiver endpoint'iniz — request gelir, doğrularsınız.
# Aşağıdaki dil örneklerine bakın.
import express from 'express';
import crypto from 'crypto';
const app = express();
const SECRET = process.env.TD_WEBHOOK_SECRET;
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.header('X-TD-Signature') || '';
const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
if (sig.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).send('bad signature');
}
const event = JSON.parse(req.body.toString());
console.log(`Olay: ${event.event} (tenant ${event.tenant_id})`);
res.json({ ok: true });
});
app.listen(3000);
import os, hmac, hashlib
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ['TD_WEBHOOK_SECRET'].encode()
@app.post('/webhook')
def webhook():
sig = request.headers.get('X-TD-Signature', '')
expected = 'sha256=' + hmac.new(SECRET, request.data, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, expected):
abort(401)
event = request.get_json()
print(f"Olay: {event['event']} (tenant {event['tenant_id']})")
return {'ok': True}
$secret = getenv('TD_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_TD_SIGNATURE'] ?? '';
$expect = 'sha256=' . hash_hmac('sha256', $body, $secret);
if (!hash_equals($expect, $sig)) {
http_response_code(401);
exit('bad signature');
}
$event = json_decode($body, true);
file_put_contents('webhook.log', $event['event'] . " tenant=" . $event['tenant_id'] . "\n", FILE_APPEND);
echo json_encode(['ok' => true]);
http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
secret := []byte(os.Getenv("TD_WEBHOOK_SECRET"))
mac := hmac.New(sha256.New, secret)
mac.Write(body)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
sig := r.Header.Get("X-TD-Signature")
if !hmac.Equal([]byte(expected), []byte(sig)) {
http.Error(w, "bad signature", http.StatusUnauthorized)
return
}
var event map[string]any
json.Unmarshal(body, &event)
log.Printf("Olay: %v (tenant %v)", event["event"], event["tenant_id"])
w.Write([]byte(`{"ok":true}`))
})
Tüm sayfaları gezerek toplam
Cursor-based pagination ile rate-limit'e takılmadan tüm kayıtları çek.
# Loop curl'da pratik değil — Node/Python örneğine bakın.
async function fetchAll(url, key) {
const all = [];
let cursor = null;
while (true) {
const u = new URL(url);
u.searchParams.set('limit', '100');
if (cursor) u.searchParams.set('cursor', cursor);
const r = await fetch(u, { headers: { Authorization: `Bearer ${key}` } });
if (r.status === 429) {
await new Promise(s => setTimeout(s, (+r.headers.get('Retry-After') || 60) * 1000));
continue;
}
const { data, has_more, next_cursor } = await r.json();
all.push(...data);
if (!has_more) return all;
cursor = next_cursor;
}
}
const customers = await fetchAll('https://teknikdanisman.net/api/v1/customers.php', process.env.TD_API_KEY);
console.log(`Toplam ${customers.length} müşteri`);
import os, time, requests
def fetch_all(url, key):
out, cursor = [], None
while True:
params = {'limit': 100}
if cursor: params['cursor'] = cursor
r = requests.get(url, params=params, headers={'Authorization': f'Bearer {key}'})
if r.status_code == 429:
time.sleep(int(r.headers.get('Retry-After', 60)))
continue
r.raise_for_status()
body = r.json()
out.extend(body['data'])
if not body['has_more']: return out
cursor = body['next_cursor']
customers = fetch_all('https://teknikdanisman.net/api/v1/customers.php', os.environ['TD_API_KEY'])
print(f"Toplam {len(customers)} müşteri")
function fetch_all(string $url, string $key): array {
$all = []; $cursor = null;
while (true) {
$u = $url . '?limit=100' . ($cursor ? '&cursor=' . $cursor : '');
$ch = curl_init($u);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key],
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$hdrSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
curl_close($ch);
if ($code === 429) { sleep(60); continue; }
$body = json_decode(substr($resp, $hdrSize), true);
$all = array_merge($all, $body['data']);
if (!$body['has_more']) return $all;
$cursor = $body['next_cursor'];
}
}
$customers = fetch_all('https://teknikdanisman.net/api/v1/customers.php', getenv('TD_API_KEY'));
echo "Toplam " . count($customers) . " müşteri\n";
func fetchAll(url, key string) ([]map[string]any, error) {
var all []map[string]any
cursor := ""
for {
u := url + "?limit=100"
if cursor != "" { u += "&cursor=" + cursor }
req, _ := http.NewRequest("GET", u, nil)
req.Header.Set("Authorization", "Bearer "+key)
resp, err := http.DefaultClient.Do(req)
if err != nil { return nil, err }
if resp.StatusCode == 429 {
time.Sleep(60 * time.Second)
resp.Body.Close()
continue
}
var body struct {
Data []map[string]any `json:"data"`
HasMore bool `json:"has_more"`
NextCursor *int `json:"next_cursor"`
}
json.NewDecoder(resp.Body).Decode(&body)
resp.Body.Close()
all = append(all, body.Data...)
if !body.HasMore { return all, nil }
cursor = fmt.Sprint(*body.NextCursor)
}
}
Daha fazlası
Tüm endpoint'ler, request/response şemaları ve query parametreleri için OpenAPI referansı; tek tıkla deneme için Postman collection. Hata kodları → Error reference.