> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flextell.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Veri imha talepleri

> KVKK veri imha taleplerini oluşturmayı, durumlarını, yeniden göndermeyi ve sertifikayı anlatır.

Bir hasta KVKK kapsamında kişisel verilerinin imhasını istediğinde, klinik personeli bu kaynakla bir **veri imha talebi** açar. Hasta, kendisine iletilen onay bağlantısından işlemi onaylar. Onayın ardından hastanın kişisel veri alanları geri alınamaz biçimde maskelenir ve klinik bir **Veri İmha Sertifikası** (PDF) alır.

Süreç iki taraflıdır. Siz API ile talebi açar ve izlersiniz, hasta ise herkese açık onay sayfasında işlemi kendisi onaylar. Entegrasyonunuz bu onayı veremez.

Panel anlatımı için [Veri İmha Talepleri (panel)](/panel/sistem/veri-imha-talepleri) sayfasına bakın.

<Warning>
  İmha geri alınamaz ve Geri Dönüşüm Kutusu'ndan geri getirilemez. Silme ile imha ayrı süreçlerdir. Silme için [Silme yaşam döngüsü](/api/istekler/silme-yasam-dongusu) sayfasına bakın. İmha etmeden önce mutlaka [kapsam önizlemesi](#talep-oluşturma) isteği yapın.
</Warning>

## Endpoint özeti

Tüm endpoint'ler `/api/v1` altındadır. `Authorization: Bearer <access_token>` ve `X-Tenant: <tenant_id>` başlıkları zorunludur. Scope ve izin ilişkisi için [Scope'lar](/api/kimlik-dogrulama/scopelar) ve [İzinler ve görünürlük](/api/izinler-ve-gorunurluk) sayfalarına bakın.

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| GET | `/data-erasure-requests` | Talepleri listeler. | `data_erasure_requests:read` | `View:DataErasureRequests` |
| GET | `/data-erasure-requests/{id}` | Tek talebi getirir. | `data_erasure_requests:read` | `View:DataErasureRequests` |
| GET | `/data-erasure-requests/customers/{customerId}/scope` | Hastanın imha kapsamını önizler. | `data_erasure_requests:write` | `Create:DataErasureRequests` |
| POST | `/data-erasure-requests/customers/{customerId}` | Hasta için talep açar. | `data_erasure_requests:write` | `Create:DataErasureRequests` |
| POST | `/data-erasure-requests/{id}/resend` | Yeni bağlantı üretir ve hastaya gönderir. | `data_erasure_requests:write` | `Create:DataErasureRequests` |
| POST | `/data-erasure-requests/{id}/link` | Yeni bağlantı üretir, URL'yi size döndürür. | `data_erasure_requests:write` | `CopyLink:DataErasureRequests` |
| POST | `/data-erasure-requests/{id}/cancel` | Talebi iptal eder. | `data_erasure_requests:write` | `Cancel:DataErasureRequests` |
| POST | `/data-erasure-requests/{id}/retry` | Başarısız talebi yeniden çalıştırır. | `data_erasure_requests:write` | `Retry:DataErasureRequests` |
| GET | `/data-erasure-requests/{id}/certificate` | Sertifika için geçici indirme URL'si verir. | `data_erasure_requests:read` | `View:DataErasureRequests` |

İzinler rol editöründe **Veri İmha Talepleri** grubunda görünür: **Görüntüle**, **Oluştur**, **İptal Et**, **Tekrar Dene** ve **Onay Bağlantısını Kopyala**. İmha geri alınamadığı için bu izinleri rollere bilinçli olarak vermeniz gerekir.

<Note>
  Kurulum sihirbazı tamamlanmamış bir klinikte bu endpoint'ler `428 SETUP_REQUIRED` döndürür. Ayrıntı için [Erişim kilitleri](/api/istekler/erisim-kilitleri) sayfasına bakın.
</Note>

## Talep durumları

Bir talep `status` alanında şu değerlerden birini taşır.

| `status` | Arayüz etiketi | Son durum mu | Anlamı |
| - | - | - | - |
| `pending_verification` | Hasta onayı bekleniyor | Hayır | Bağlantı gönderildi, hasta henüz onaylamadı. |
| `processing` | İşleniyor | Hayır | Hasta onayladı, imha çalışıyor. |
| `completed` | Tamamlandı | Evet | İmha bitti, sertifika alınabilir. |
| `failed` | Başarısız | Evet | İmha yarıda kaldı. Yalnızca bir kullanıcı yeniden deneyebilir. |
| `expired` | Süresi doldu | Evet | Hasta bağlantı süresi içinde onaylamadı. |
| `cancelled` | İptal edildi | Evet | Personel talebi iptal etti. |

```mermaid theme={null}
flowchart LR
  A["Talep açıldı"] --> B["Hasta onayı bekleniyor"]
  B -->|"Hasta onaylar"| C["İşleniyor"]
  C --> D["Tamamlandı"]
  C --> E["Başarısız"]
  E -->|"Tekrar dene"| C
  B -->|"Süre dolar"| F["Süresi doldu"]
  B -->|"Personel iptal eder"| G["İptal edildi"]
```

Hasta onay sayfasında onayladığında imha aynı istek içinde hemen çalışır. Bu yüzden `processing` durumunu genellikle yalnızca kısa süre görürsünüz.

Hangi eylemin şu an yapılabildiğini `state_allows` nesnesinden okuyun. Nesnenin anahtarları `resend`, `cancel`, `retry` ve `certificate` değerleridir. Durumdan kendiniz çıkarım yapmak yerine bu alanlara göre buton gösterin ya da çağrı yapın.

### Talep nesnesi

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | sayı | Talep ID'si. |
| `customer_id`, `customer` | sayı, nesne | İmha istenen hasta. Hasta kaydı sonradan silinirse `customer_id` boş olur. |
| `requested_by`, `cancelled_by` | nesne | Talebi açan ve iptal eden kullanıcı. |
| `status` | metin | Yukarıdaki tablodaki değerler. |
| `request_reason` | metin | Açarken girdiğiniz gerekçe. |
| `scope_summary` | nesne | Talep açılırken dondurulan `will_mask` ve `will_keep` listeleri. |
| `verification_channel` | metin | Bağlantının gönderildiği kanal (örneğin `whatsapp`, `telegram`). Kanal kaydı yoksa `link`. |
| `verification_expires_at` | tarih-saat | Bağlantının geçerlilik sonu. |
| `resend_count`, `last_sent_at` | sayı, tarih-saat | Yeniden gönderme sayacı ve son gönderim zamanı. |
| `verified_at` | tarih-saat | Hastanın onay zamanı. |
| `executed_at`, `execution_report` | tarih-saat, nesne | İmhanın bittiği zaman ve ilişki başına maskelenen kayıt sayıları. |
| `certificate_code` | metin | Sertifika kodu (10 karakter, büyük harf). |
| `cancelled_at`, `cancellation_reason` | tarih-saat, metin | İptal zamanı ve gerekçesi. |
| `state_allows` | nesne | Şu an yapılabilen eylemler. |
| `created_at`, `updated_at` | tarih-saat | Kayıt zamanları. |

Yanıtlar onay token'ını ya da özetini hiçbir zaman içermez.

### Listeleme

`GET /data-erasure-requests` isteği şu parametreleri alır. Genel kurallar için [Filtreleme ve sıralama](/api/istekler/filtreleme-ve-siralama) ve [Sayfalama](/api/istekler/sayfalama) sayfalarına bakın.

| Parametre | Açıklama |
| - | - |
| `status` | Duruma göre süzer. |
| `created_at_from`, `created_at_to` | Oluşturma tarihi aralığı. |
| `sort_by` | `created_at` (varsayılan), `verified_at`, `executed_at`, `status`. Varsayılan sıra yeniden eskiye. |
| `sort_order` | `asc` ya da `desc`. |
| `per_page`, `page` | Sayfalama. `per_page` varsayılanı 15'tir. |

## Talep oluşturma

<Steps>
  <Step title="Kapsamı önizleyin">
    `GET /data-erasure-requests/customers/{customerId}/scope` isteği hiçbir şey yazmaz. Hangi kayıtların maskeleneceğini (`will_mask`) ve hangilerinin yasal nedenle saklanacağını (`will_keep`) döndürür. Yalnızca sayısı sıfırdan büyük ilişkiler listelenir. Silinmiş (Geri Dönüşüm Kutusu'ndaki) kayıtlar da sayıya girer.
  </Step>

  <Step title="Hastanın talebini doğrulayın">
    Hastanın talebini nasıl ilettiğini (telefon, e-posta, yüz yüze) `reason` alanına yazın. Hastayla talebi bizzat teyit ettiyseniz `confirmed_with_patient` alanını `true` gönderin.
  </Step>

  <Step title="Talebi açın">
    `POST /data-erasure-requests/customers/{customerId}` isteği talebi `pending_verification` durumunda açar ve onay bağlantısını hastaya iletmeyi dener.
  </Step>
</Steps>

<ParamField body="reason" type="string" required>
  Talebin dayanağı. En çok 2000 karakter.
</ParamField>

<ParamField body="confirmed_with_patient" type="boolean" required>
  Hastanın talebini bizzat teyit ettiğinizi bildirir. `true` olmalıdır, aksi hâlde `422` alırsınız.
</ParamField>

Bir hasta için aynı anda yalnızca bir açık talep olabilir. Hastanın verileri zaten imha edilmişse ya da açık bir talep varsa `409 ERASURE_REQUEST_CONFLICT` döner.

<CodeGroup>
  ```bash Kapsam önizlemesi theme={null}
  curl "https://app.flextell.ai/api/v1/data-erasure-requests/customers/123/scope" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>"
  ```

  ```bash Talep açma theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/data-erasure-requests/customers/123" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "Hasta telefonla verilerinin imhasını talep etti.",
      "confirmed_with_patient": true
    }'
  ```
</CodeGroup>

Kapsam yanıtı şu biçimdedir. Etiketler Türkçe döner.

```json theme={null}
{
  "success": true,
  "data": {
    "customer": { "id": 123 },
    "scope": {
      "will_mask": [
        { "relation": "self", "label": "Hasta kaydı (ad, telefon, e-posta, kimlik bilgileri)", "count": 1 },
        { "relation": "appointments", "label": "Randevular", "count": 4 }
      ],
      "will_keep": [
        { "relation": "invoices", "label": "Faturalar", "count": 2, "reason": "VUK m.253 / TTK m.82 uyarınca saklanması zorunlu" }
      ]
    }
  }
}
```

Bu örnekte yalnızca ilgili alanlar gösterilmiştir. Maskelenen ilişkiler şunlardır: kimlik bilgileri, sohbetler, randevular, satışlar, teklifler, destek talepleri, hasta formları, notlar ve dosyalar. Kapsamı her zaman önizlemedeki `will_mask` listesine göre değerlendirin.

Talep açma `201` ile döner. `delivery.delivered` değeri bağlantının hastaya gönderilip gönderilemediğini söyler.

```json theme={null}
{
  "success": true,
  "data": {
    "request": {
      "id": 45,
      "customer_id": 123,
      "status": "pending_verification",
      "request_reason": "Hasta telefonla verilerinin imhasını talep etti.",
      "verification_channel": "whatsapp",
      "verification_expires_at": "2026-10-15T14:30:00+03:00",
      "resend_count": 0,
      "state_allows": { "resend": true, "cancel": true, "retry": false, "certificate": false }
    },
    "delivery": { "delivered": true, "channel": "whatsapp" }
  }
}
```

<Info>
  `delivery.delivered` değeri `false` ise hastaya ulaşılabilecek bir iletişim kanalı yoktur. Talep yine de oluşmuştur. [Linki yeniden gönderme](#linki-yeniden-gönderme) bölümündeki `link` endpoint'i ile URL'yi alıp hastaya kendiniz iletebilirsiniz.
</Info>

### Onay bağlantısı

Bağlantı 72 saat geçerlidir. Hasta bağlantıyı herkese açık `/veri-imha/{token}` sayfasında açar. Sayfa yalnızca kayıt sayılarını, tarihleri ve klinik adını gösterir, hasta bilgisi göstermez. Hasta `SİL` ifadesini yazar ve **Bu işlemin geri alınamayacağını anladım.** kutusunu işaretler. Onay sonrasında imha hemen çalışır.

### İptal ve yeniden deneme

`POST /data-erasure-requests/{id}/cancel` isteği yalnızca `pending_verification` durumundaki talebi iptal eder. İsteğe bağlı `reason` alanı (en çok 2000 karakter) iptal gerekçesini kaydeder.

`POST /data-erasure-requests/{id}/retry` isteği yalnızca `failed` durumundaki talebi yeniden çalıştırır. Yeniden deneme eşzamanlı çalışır ve yanıtta son durumu (`completed` ya da `failed`) döndürür. Önceki deneme yarıda kaldıysa bazı kayıtlar zaten maskelenmiş olabilir, yeniden çalıştırma kalanları maskeler. Aynı talep için iki yeniden deneme aynı anda çalışmaz.

## Linki yeniden gönderme

Hasta bağlantıyı bulamazsa ya da süre dolmak üzereyse iki yol vardır.

| Endpoint | Ne yapar | Yanıt |
| - | - | - |
| `POST /data-erasure-requests/{id}/resend` | Yeni bağlantı üretir ve hastaya gönderir. | Güncel talep nesnesi. |
| `POST /data-erasure-requests/{id}/link` | Yeni bağlantı üretir, hastaya gönderir ve URL'yi size de döndürür. | `request_id`, `url`, `expires_at`. |

İki endpoint de yeni bir bağlantı üretir ve eski bağlantı geçersiz olur. İkisi de aynı yeniden gönderme hakkından düşer.

<Warning>
  `link` yanıtındaki URL, hastanın onayı yerine geçer. Bu bağlantıyı yalnızca hastaya iletmek için kullanın. Bağlantıyı almanız etkinlik günlüğüne `erasure_link_copied` olayı olarak kaydedilir. Bu yüzden `link` için ayrı bir izin (`CopyLink:DataErasureRequests`) gerekir.
</Warning>

Yeniden gönderme kuralları:

* Talep `pending_verification` durumunda olmalıdır.
* Bir talep için en çok 3 kez yeniden gönderebilirsiniz.
* İki gönderim arasında en az 5 dakika geçmelidir.

Kurallardan biri sağlanmazsa `409 ERASURE_REQUEST_CONFLICT` ve `Bu talep için şu anda yeni bir bağlantı gönderilemez.` mesajı döner.

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/data-erasure-requests/45/link" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>"
```

```json theme={null}
{
  "success": true,
  "data": {
    "request_id": 45,
    "url": "https://app.flextell.ai/veri-imha/<token>",
    "expires_at": "2026-10-16T09:15:00+03:00"
  }
}
```

## Sertifika

Talep `completed` olduğunda `GET /data-erasure-requests/{id}/certificate` isteği sertifika PDF'si için geçici bir URL döndürür.

```json theme={null}
{
  "success": true,
  "data": {
    "request_id": 45,
    "certificate_code": "ABCDE12345",
    "url": "https://<geçici-indirme-adresi>",
    "expires_at": "2026-10-13T14:35:00+03:00"
  }
}
```

URL 5 dakika geçerlidir. Süre dolunca aynı endpoint'i yeniden çağırarak yeni bir URL alın. PDF'in başlığı **Veri İmha Sertifikası**'dır ve **Anonimleştirilen Kayıtlar** ile **Yasal Olarak Saklanan Kayıtlar** bölümlerini içerir.

| HTTP | Kod | Ne zaman |
| - | - | - |
| 409 | `ERASURE_REQUEST_CONFLICT` | Talep henüz `completed` değil. |
| 500 | `ERASURE_CERTIFICATE_UNAVAILABLE` | Sertifika üretilemedi. |
| 503 | `ERASURE_CERTIFICATE_UNAVAILABLE` | İndirme URL'si üretilemedi. |

## İmha sonrası davranış

İmha hiçbir kaydı silmez. Hastanın ve ilişkili kayıtların kişisel veri alanları maskelenmiş değerlerle yeniden yazılır.

| Veri türü | Saklanan biçim |
| - | - |
| Ad | Her sözcüğün ilk 2 harfi kalır: `Ah••• Öz•••` |
| Telefon | Ülke kodu, ilk hane ve son 2 hane kalır: `+90 5•• ••• •• 33` |
| E-posta | İlk karakter ve alan adı kalır: `a•••@example.com` |
| Kimlik numarası | İlk 3 ve son 2 hane kalır: `123••••••01` |
| Pasaport numarası | İlk 2 ve son 2 karakter kalır: `U1•••••78` |
| Adres | `••••••` |
| Doğum tarihi | Yalnızca yıl kalır, tarih `1985-01-01` olur. |
| Serbest metin (örneğin not içeriği) | `[İmha edildi]` |

Faturalar yasal saklama yükümlülüğü nedeniyle olduğu gibi kalır (VUK m.253 / TTK m.82).

Hasta imha edildikten sonra:

* Hastayı ya da ona bağlı bir kaydı değiştiren her yazma isteği `409 CUSTOMER_ERASED` döndürür. Mesaj `Bu hastanın verileri imha edildi; kayıt salt okunurdur.` biçimindedir.
* Okuma yanıtlarında `record_state.is_read_only` değeri `true` olur. `record_state` için [Hastalar](/api/kaynaklar/hastalar) sayfasına bakın.
* Hasta birleştirmeye katılamaz. İmha edilmiş ya da açık imha talebi olan hasta için `422 MERGE_CUSTOMER_ERASED` döner.
* Aynı hasta için yeni talep açılamaz (`409 ERASURE_REQUEST_CONFLICT`).

## Hata kodları

| Kod | HTTP | Ne zaman |
| - | - | - |
| `ERASURE_REQUEST_CONFLICT` | 409 | Talep o geçişe izin vermiyor: hasta zaten imha edilmiş, açık talep var, yanlış durumda gönderme, iptal, yeniden deneme ya da sertifika. |
| `ERASURE_SCOPE_UNAVAILABLE` | 500 | İmha kapsamı hazırlanamadı (önizleme ve talep açma). |
| `ERASURE_CERTIFICATE_UNAVAILABLE` | 500, 503 | Sertifika üretilemedi ya da URL'si imzalanamadı. |
| `CUSTOMER_ERASED` | 409 | İmha edilmiş hasta üzerinde yazma denemesi. |
| `SETUP_REQUIRED` | 428 | Kliniğin kurulumu tamamlanmamış. |

`ERASURE_REQUEST_CONFLICT` yanıtlarının `message` alanı `Accept-Language` başlığından bağımsız olarak Türkçe gelir. Aşağıdaki iletiler kullanılır:

* `Bu hastanın verileri zaten imha edilmiş.`
* `Bu hasta için zaten açık bir imha talebi var.`
* `Bu talep için şu anda yeni bir bağlantı gönderilemez.`
* `Bu talep artık iptal edilemez.`
* `Bu talep artık tekrar çalıştırılamaz.`
* `Bu bağlantı artık geçerli değil.`

Sertifika için talep henüz tamamlanmamışsa `İmha talebi bu geçişi gerçekleştiremez.` iletisi gelir. Bulunamayan talep için `404` (`Veri imha talebi bulunamadı`), bulunamayan hasta için `404` (`Hasta bulunamadı`) döner. Genel hata biçimi için [Hata kodları](/api/istekler/hata-kodlari) sayfasına bakın.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.