# Kayıt ve oturumlar

Bu üç endpoint kişi hesaplarını ve oturum token'larını yönetir. `register` ve `login`, kişiyle birlikte bir `token` döner; bunu kişi kimliği doğrulanmış endpoint'lerde `X-Customer-Token` olarak gönderin. Üçü de API anahtarınızda `contacts:write` scope'unu gerektirir (`customers:write` kabul edilir).

## POST /v1/api/contacts/register

Mevcut entegrasyonlar için `/v1/api/customers/register` üzerinde de sunulur; request ve response birebir aynıdır.

Bir storefront kişi hesabı kaydeder. Oluşturulan kişiyi ve bir oturum token'ını döner. E-posta zaten bir misafir satırına aitse (Commerce modülündeki sepet e-posta yakalamayla oluşturulmuş), misafir yerinde yükseltilir: aynı `id`, sipariş geçmişi korunur, ad ve parola bu request'ten ayarlanır. Yalnızca gerçek (misafir olmayan) bir hesaba ait e-posta reddedilir. Ek rate limit: IP başına dakikada 10 request.

### Body parametreleri

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `name` | string | Evet | Ad soyad. En fazla 150 karakter. |
| `email` | string | Evet | Geçerli e-posta adresi, en fazla 255 karakter. Sunucu tarafında küçük harfe çevrilir. Mevcut, misafir olmayan bir hesaba ait olmamalıdır. |
| `password` | string | Evet | En az 8 karakter. |

```bash title="Request"
curl -X POST https://api.borkol.com/v1/api/contacts/register \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"name":"Jane Doe","email":"jane@example.com","password":"s3cret-pass"}'
```

```javascript title="Request (JS)"
const res = await fetch("https://api.borkol.com/v1/api/contacts/register", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Jane Doe",
    email: "jane@example.com",
    password: "s3cret-pass",
  }),
});
const { data: contact, token } = await res.json();
```

Durum: `201 Created`.

```json title="Response"
{
  "data": {
    "id": "9d4e2f1a-6b3c-4f8e-9a1d-2c5b7e8f0a3d",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": null,
    "kind": "person",
    "company_name": null,
    "registration_number": null,
    "vat_id": null,
    "external_id": null,
    "display_name": "Jane Doe",
    "created_at": "2026-08-14T10:32:11+00:00"
  },
  "token": "12|Fq8sT3vY6wZx9aBcDeFgHiJkLmNoPqRsTuVwXyZ0"
}
```

### Hatalar

- Misafir olmayan bir hesap e-postayı zaten kullanıyorsa `errors.email` `["Email already registered."]` ile `422`.
- Alan doğrulama hataları için `422` (eksik ad, geçersiz e-posta, 8 karakterden kısa parola).
- IP başına dakikada 10 request limiti aşıldığında `429`.

## POST /v1/api/contacts/login

Mevcut entegrasyonlar için `/v1/api/customers/login` üzerinde de sunulur; request ve response birebir aynıdır.

Bir kişiyi e-posta ve parolayla doğrular. Kişiyi ve yeni bir oturum token'ını döner, hesabın `last_login_at` alanını günceller. Denetim zamanlama açısından güvenlidir (timing-safe) ve e-postanın var olup olmadığını asla açığa vurmaz: yanlış parola, bilinmeyen e-posta ve (parolası olmayan) misafir hesabı, hepsi aynı 422 ile başarısız olur. Ek rate limit: IP başına dakikada 10 request.

### Body parametreleri

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `email` | string | Evet | Geçerli e-posta adresi. Aramadan önce sunucu tarafında küçük harfe çevrilir. |
| `password` | string | Evet | Hesap parolası. |

```bash title="Request"
curl -X POST https://api.borkol.com/v1/api/contacts/login \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","password":"s3cret-pass"}'
```

Durum: `200 OK`.

```json title="Response"
{
  "data": {
    "id": "9d4e2f1a-6b3c-4f8e-9a1d-2c5b7e8f0a3d",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "+31612345678",
    "kind": "person",
    "company_name": null,
    "registration_number": null,
    "vat_id": null,
    "external_id": null,
    "display_name": "Jane Doe",
    "created_at": "2026-08-14T10:32:11+00:00"
  },
  "token": "13|Gh7rS2uX5vWy8zAbCdEfGhIjKlMnOpQrStUvWxYz"
}
```

### Hatalar

- Yanlış e-posta veya yanlış parola için `errors.email` `["Invalid credentials."]` ile `422`. Hata her zaman `email` anahtarındadır.
- IP başına dakikada 10 request limiti aşıldığında `429`.

## POST /v1/api/contacts/logout

Mevcut entegrasyonlar için `/v1/api/customers/logout` üzerinde de sunulur; request ve response birebir aynıdır.

`X-Customer-Token` içinde verilen kişi oturum token'ını iptal eder. Kişi kimlik doğrulamasını geçmek için header mevcut ve geçerli olmalıdır: halihazırda geçerli bir token iptal edilir ve request 204 döner; zaten iptal edilmiş veya bilinmeyen bir token ise 401 `{"message": "Invalid customer token."}` ile kimlik doğrulamada başarısız olur.

### Header'lar

| Ad | Tür | Zorunlu | Açıklama |
| --- | --- | --- | --- |
| `X-Customer-Token` | string | Evet | İptal edilecek oturum token'ı. |

Body yoktur.

```bash title="Request"
curl -X POST https://api.borkol.com/v1/api/contacts/logout \
  -H "Authorization: Bearer {api_key}" \
  -H "X-Customer-Token: 13|Gh7rS2uX5vWy8zAbCdEfGhIjKlMnOpQrStUvWxYz"
```

Durum: `204 No Content`. Response'un gövdesi yoktur.

### Hatalar

- `X-Customer-Token` eksik veya geçersiz olduğunda `401` `{"message":"Invalid customer token."}`.
