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

# API de consentimentos

> Gerir consentimentos via API Key (integração servidor a servidor)

Esta página descreve os endpoints **`/api/v1/consents`** para integração **server-to-server** com **API Key**. Eles são distintos do fluxo público do banner (`POST /api/v1/public/consent`), que usa o header `X-Site-Token`.

Para obter e usar uma API Key, consulte [API Key](./api-key).

## Autenticação

Inclua o header em toda chamada:

```http theme={null}
Authorization: Bearer sk-...
```

Cada requisição bem-sucedida consome **1** unidade da cota mensal do plano (`api_access`).

## Endpoints

| Método   | Caminho                                   | Descrição                                                                                          |
| -------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `POST`   | `/api/v1/consents`                        | Cria um registro de consentimento para um `site_id` seu.                                           |
| `POST`   | `/api/v1/consents/batch`                  | Ingere até **1000** consentimentos por chamada (Stripe-like, com array `results` por linha).       |
| `GET`    | `/api/v1/consents`                        | Lista com filtros e paginação por `cursor`.                                                        |
| `GET`    | `/api/v1/consents/{id}`                   | Detalhe de um consentimento.                                                                       |
| `PUT`    | `/api/v1/consents/{id}`                   | Atualiza aceite e/ou preferências (alterações auditadas).                                          |
| `DELETE` | `/api/v1/consents/{id}`                   | Exclusão lógica (LGPD / direito ao esquecimento).                                                  |
| `GET`    | `/api/v1/consents/{id}/history`           | Trilha de auditoria do consentimento.                                                              |
| `GET`    | `/api/v1/consents/{id}/receipt`           | Recibo canônico (`version: "1.0"`) pronto para arquivar como evidência regulatória.                |
| `DELETE` | `/api/v1/consents/by-subject/{subjectId}` | DSAR: apaga lógicamente todos os consentimentos do titular (`?site_id=` opcional para restringir). |

Especificação OpenAPI completa, com schemas e exemplos por endpoint, está disponível na aba **API Reference**.

## Criar consentimento

Corpo mínimo: `site_id` é obrigatório; os demais campos refinam a evidência. Resposta `201` com o `ConsentDTO` completo.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.consentfly.com.br/api/v1/consents \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
      "subject_id": "user_sha256_a1b2c3d4e5f6",
      "consent_id": "analytics-2026-05",
      "accepted": true,
      "preferences": { "analytics": true, "marketing": false, "functional": true },
      "policy_version": 3,
      "user_agent": "MeuBackend/1.0"
    }'
  ```

  ```javascript Node theme={null}
  const res = await fetch("https://www.consentfly.com.br/api/v1/consents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      site_id: "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
      subject_id: "user_sha256_a1b2c3d4e5f6",
      consent_id: "analytics-2026-05",
      accepted: true,
      preferences: { analytics: true, marketing: false, functional: true },
      policy_version: 3,
      user_agent: "MeuBackend/1.0",
    }),
  });
  const consent = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://www.consentfly.com.br/api/v1/consents",
      headers={
          "Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}",
          "Content-Type": "application/json",
      },
      json={
          "site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
          "subject_id": "user_sha256_a1b2c3d4e5f6",
          "consent_id": "analytics-2026-05",
          "accepted": True,
          "preferences": {"analytics": True, "marketing": False, "functional": True},
          "policy_version": 3,
          "user_agent": "MeuBackend/1.0",
      },
  )
  consent = res.json()
  ```

  ```go Go theme={null}
  body, _ := json.Marshal(map[string]any{
      "site_id":        "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
      "subject_id":     "user_sha256_a1b2c3d4e5f6",
      "consent_id":     "analytics-2026-05",
      "accepted":       true,
      "preferences":    map[string]bool{"analytics": true, "marketing": false, "functional": true},
      "policy_version": 3,
      "user_agent":     "MeuBackend/1.0",
  })
  req, _ := http.NewRequest("POST", "https://www.consentfly.com.br/api/v1/consents", bytes.NewReader(body))
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  req.Header.Set("Content-Type", "application/json")
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Listar consentimentos

`GET /api/v1/consents` retorna uma página paginada por cursor. Filtre por `site_id`, `subject_id`, `consent_id`, `accepted`, e janela temporal `from`/`to` (ISO 8601). `limit` padrão é 50, máximo 100. Use `next_cursor` da resposta para a próxima página; quando vier `null`, você chegou ao fim.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://www.consentfly.com.br/api/v1/consents?site_id=6b8b4567-327a-4d10-92a5-9e8c4f5a7d12&accepted=true&limit=50" \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const params = new URLSearchParams({
    site_id: "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
    accepted: "true",
    limit: "50",
  });
  const res = await fetch(`https://www.consentfly.com.br/api/v1/consents?${params}`, {
    headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` },
  });
  const { data, next_cursor } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.get(
      "https://www.consentfly.com.br/api/v1/consents",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
      params={
          "site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12",
          "accepted": "true",
          "limit": 50,
      },
  )
  page = res.json()  # { data: [...], limit: 50, next_cursor: "..." }
  ```

  ```go Go theme={null}
  u, _ := url.Parse("https://www.consentfly.com.br/api/v1/consents")
  q := u.Query()
  q.Set("site_id", "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12")
  q.Set("accepted", "true")
  q.Set("limit", "50")
  u.RawQuery = q.Encode()
  req, _ := http.NewRequest("GET", u.String(), nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Detalhe de um consentimento

`GET /api/v1/consents/{id}` retorna o `ConsentDTO` completo.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://www.consentfly.com.br/api/v1/consents/01HK8VV4P9R3T8M2A2YZJ7HQ5Q \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q";
  const res = await fetch(`https://www.consentfly.com.br/api/v1/consents/${id}`, {
    headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` },
  });
  const consent = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  res = requests.get(
      f"https://www.consentfly.com.br/api/v1/consents/{id}",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
  )
  consent = res.json()
  ```

  ```go Go theme={null}
  id := "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  req, _ := http.NewRequest("GET", "https://www.consentfly.com.br/api/v1/consents/"+id, nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Atualizar aceite / preferências

`PUT /api/v1/consents/{id}` aceita `accepted` e/ou `preferences`. A alteração é registrada na trilha de auditoria do consentimento.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT https://www.consentfly.com.br/api/v1/consents/01HK8VV4P9R3T8M2A2YZJ7HQ5Q \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "accepted": false,
      "preferences": { "analytics": false, "marketing": false, "functional": true }
    }'
  ```

  ```javascript Node theme={null}
  const id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q";
  await fetch(`https://www.consentfly.com.br/api/v1/consents/${id}`, {
    method: "PUT",
    headers: {
      Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      accepted: false,
      preferences: { analytics: false, marketing: false, functional: true },
    }),
  });
  ```

  ```python Python theme={null}
  import os, requests

  id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  requests.put(
      f"https://www.consentfly.com.br/api/v1/consents/{id}",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
      json={
          "accepted": False,
          "preferences": {"analytics": False, "marketing": False, "functional": True},
      },
  )
  ```

  ```go Go theme={null}
  id := "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  body, _ := json.Marshal(map[string]any{
      "accepted":    false,
      "preferences": map[string]bool{"analytics": false, "marketing": false, "functional": true},
  })
  req, _ := http.NewRequest("PUT", "https://www.consentfly.com.br/api/v1/consents/"+id, bytes.NewReader(body))
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  req.Header.Set("Content-Type", "application/json")
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Excluir (soft-delete)

`DELETE /api/v1/consents/{id}` marca o consentimento como excluído (`deleted_at` preenchido). O histórico permanece para evidência regulatória.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://www.consentfly.com.br/api/v1/consents/01HK8VV4P9R3T8M2A2YZJ7HQ5Q \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q";
  await fetch(`https://www.consentfly.com.br/api/v1/consents/${id}`, {
    method: "DELETE",
    headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` },
  });
  ```

  ```python Python theme={null}
  import os, requests

  id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  requests.delete(
      f"https://www.consentfly.com.br/api/v1/consents/{id}",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
  )
  ```

  ```go Go theme={null}
  id := "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  req, _ := http.NewRequest("DELETE", "https://www.consentfly.com.br/api/v1/consents/"+id, nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Trilha de auditoria

`GET /api/v1/consents/{id}/history` devolve todos os snapshots já registrados para aquele consentimento — útil para apresentar a "linha do tempo" da decisão do titular em auditoria.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://www.consentfly.com.br/api/v1/consents/01HK8VV4P9R3T8M2A2YZJ7HQ5Q/history \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q";
  const res = await fetch(`https://www.consentfly.com.br/api/v1/consents/${id}/history`, {
    headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` },
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  res = requests.get(
      f"https://www.consentfly.com.br/api/v1/consents/{id}/history",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
  )
  history = res.json()["data"]
  ```

  ```go Go theme={null}
  id := "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  req, _ := http.NewRequest("GET", "https://www.consentfly.com.br/api/v1/consents/"+id+"/history", nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Batch ingestion

Para importar dados históricos ou sincronizar lotes grandes use `POST /api/v1/consents/batch` (até **1000** consentimentos por chamada). A resposta volta no formato Stripe-like: `created`, `failed`, `skipped_quota` e um array `results` indexado por linha.

A primeira linha é coberta pela cobrança do request; cada linha adicional consome **+1** unidade da cota mensal. Se a cota acabar no meio do batch, as linhas restantes voltam com `status="skipped_quota"` e nada é gravado.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.consentfly.com.br/api/v1/consents/batch \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "consents": [
        { "site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "alice_hash", "accepted": true },
        { "site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "bob_hash",   "accepted": false }
      ]
    }'
  ```

  ```javascript Node theme={null}
  await fetch("https://www.consentfly.com.br/api/v1/consents/batch", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      consents: [
        { site_id: "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", subject_id: "alice_hash", accepted: true },
        { site_id: "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", subject_id: "bob_hash",   accepted: false },
      ],
    }),
  });
  ```

  ```python Python theme={null}
  import os, requests

  requests.post(
      "https://www.consentfly.com.br/api/v1/consents/batch",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
      json={
          "consents": [
              {"site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "alice_hash", "accepted": True},
              {"site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "bob_hash",   "accepted": False},
          ]
      },
  )
  ```

  ```go Go theme={null}
  body, _ := json.Marshal(map[string]any{
      "consents": []map[string]any{
          {"site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "alice_hash", "accepted": true},
          {"site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12", "subject_id": "bob_hash", "accepted": false},
      },
  })
  req, _ := http.NewRequest("POST", "https://www.consentfly.com.br/api/v1/consents/batch", bytes.NewReader(body))
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  req.Header.Set("Content-Type", "application/json")
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Recibo regulador (DSAR)

`GET /api/v1/consents/{id}/receipt` devolve um recibo canônico cuja **forma JSON é estável** (`version: "1.0"`) — arquive-o como evidência. Inclui o titular, escolha, preferências, versão de política, país/região e timestamps.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://www.consentfly.com.br/api/v1/consents/01HK8VV4P9R3T8M2A2YZJ7HQ5Q/receipt \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q";
  const res = await fetch(`https://www.consentfly.com.br/api/v1/consents/${id}/receipt`, {
    headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` },
  });
  const receipt = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  id = "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  res = requests.get(
      f"https://www.consentfly.com.br/api/v1/consents/{id}/receipt",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
  )
  receipt = res.json()
  ```

  ```go Go theme={null}
  id := "01HK8VV4P9R3T8M2A2YZJ7HQ5Q"
  req, _ := http.NewRequest("GET", "https://www.consentfly.com.br/api/v1/consents/"+id+"/receipt", nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Direito ao esquecimento (DSAR erase)

`DELETE /api/v1/consents/by-subject/{subjectId}` apaga (logicamente) todos os consentimentos do titular sob a sua conta. O histórico continua íntegro — reguladores querem prova de que a remoção aconteceu, então apenas o `deleted_at` é marcado. Passe `?site_id=<uuid>` para limitar a um único site.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE "https://www.consentfly.com.br/api/v1/consents/by-subject/user_sha256_a1b2c3d4e5f6?site_id=6b8b4567-327a-4d10-92a5-9e8c4f5a7d12" \
    -H "Authorization: Bearer $CONSENTFLY_API_KEY"
  ```

  ```javascript Node theme={null}
  const subjectId = "user_sha256_a1b2c3d4e5f6";
  const siteId = "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12";
  const res = await fetch(
    `https://www.consentfly.com.br/api/v1/consents/by-subject/${subjectId}?site_id=${siteId}`,
    { method: "DELETE", headers: { Authorization: `Bearer ${process.env.CONSENTFLY_API_KEY}` } }
  );
  const { erased } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  subject_id = "user_sha256_a1b2c3d4e5f6"
  res = requests.delete(
      f"https://www.consentfly.com.br/api/v1/consents/by-subject/{subject_id}",
      headers={"Authorization": f"Bearer {os.environ['CONSENTFLY_API_KEY']}"},
      params={"site_id": "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12"},
  )
  erased = res.json()["erased"]
  ```

  ```go Go theme={null}
  subjectID := "user_sha256_a1b2c3d4e5f6"
  u, _ := url.Parse("https://www.consentfly.com.br/api/v1/consents/by-subject/" + subjectID)
  q := u.Query()
  q.Set("site_id", "6b8b4567-327a-4d10-92a5-9e8c4f5a7d12")
  u.RawQuery = q.Encode()
  req, _ := http.NewRequest("DELETE", u.String(), nil)
  req.Header.Set("Authorization", "Bearer "+os.Getenv("CONSENTFLY_API_KEY"))
  http.DefaultClient.Do(req)
  ```
</CodeGroup>

Resposta: `{ "subject_id": "user_sha256_a1b2c3d4e5f6", "erased": 7 }`

## Não confundir com o banner no site

| Integração           | Endpoint                      | Autenticação                   |
| -------------------- | ----------------------------- | ------------------------------ |
| Snippet no navegador | `POST /api/v1/public/consent` | `X-Site-Token` (token do site) |
| Backend / automação  | `/api/v1/consents/*`          | `Bearer sk-...`                |

## Erros frequentes

O corpo de erro segue o schema **APIErrorResponse**: campos **`error`** (código) e **`message`** (texto).

* `unauthorized` — API Key inválida ou revogada.
* `quota_exceeded` — cota mensual da API esgotada (`429`).
* `not_found` — consentimento ou site não encontrado para o utilizador da chave.
* `invalid_request` — corpo ou query inválidos (ex.: cursor malformado).

<p align="center">
  Dúvidas? <a href="mailto:suporte@consentfly.com.br">[suporte@consentfly.com.br](mailto:suporte@consentfly.com.br)</a>
</p>
