---
title: Accept or withdraw the terms
sidebar_label: Accept or withdraw the terms
sidebar_position: 13
description: Accept or withdraw the terms for the signed-in practitioner with POST /v1/me/consent/legal and get the resulting legal consent back.
---

# Accept or withdraw the terms

| Method | Path |
| --- | --- |
| `POST` | `/v1/me/consent/legal` |

[Authentication](/authentication) · [Account routes](/authentication#account-routes) · [Access policies](/access-policies)

Accepts or withdraws the terms for the signed-in practitioner and returns the resulting legal consent.

:::note
This is an account-level route. It has no `/auth/tenant/` variant. Use the access token that a [tenant sign-in](/authentication) returns.
:::

**Auth:** Bearer token of a practitioner session (the profile must be a `Practitioner`). The caller's access policy must grant `Consent:read`, `Consent:search`, `Consent:create` and `Consent:update`. Project admins skip the access policy check.
**Scope:** The caller's practitioner profile in the project of the token.

## Request

### Body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `termsAndConditionsConsent` | `boolean` | Yes | `true` accepts the currently published terms. `false` withdraws an active acceptance. |

## Behaviour

- `true` records the acceptance of the currently published terms. It creates the legal consent, or re-activates a revoked one, with a link to the terms page of your project's practitioner app and the time of acceptance.
- `false` revokes an active legal consent with `revokedReason` set to `withdrawn`. With no active consent it changes nothing.
- Accepting again on the same terms version writes nothing.
- The terms value that [`GET /v1/slim/user/consents`](/slim-apis/user/get-all-user-consents) returns changes in the same write. Other consents are not changed.
- The write is atomic. It either succeeds completely or changes nothing.
- The response has the shape of [Get legal consent](/authentication/account/get-legal-consent) and is read after the write, so it shows the new state.

## Example

```bash
curl -X POST 'https://api.sandbox.ovok.com/v1/me/consent/legal' \
  -H "Authorization: Bearer ${OVOK_TOKEN}" \
  -H 'Content-Type: application/json' \
  -d '{ "termsAndConditionsConsent": true }'
```

## Successful response

`201` — The resulting legal consent.

```json
{
  "legal": {
    "consentId": "0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
    "status": "active",
    "termsUrl": "https://app.example.com/legal/terms-and-conditions",
    "termsUpdatedAt": "2026-09-01T08:00:00.000Z",
    "acceptedAt": "2026-10-09T09:15:00.000Z",
    "revokedAt": null,
    "revokedReason": null
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `legal` | `object \| null` | The legal consent. `null` when the practitioner withdrew without ever having accepted. |
| `legal.consentId` | `string` | Id of the Consent resource that holds the acceptance. |
| `legal.status` | `"active"` \| `"revoked"` | `active` after an acceptance, `revoked` after a withdrawal. |
| `legal.termsUrl` | `string \| null` | The terms page the practitioner accepted. |
| `legal.termsUpdatedAt` | `string \| null` | When the accepted terms were last updated. ISO 8601. |
| `legal.acceptedAt` | `string \| null` | When the terms were accepted. ISO 8601. |
| `legal.revokedAt` | `string \| null` | When the acceptance was revoked. `null` while active. |
| `legal.revokedReason` | `"tos-updated"` \| `"withdrawn"` \| `null` | Why it was revoked. `null` while active. |

## Errors

| Status | Meaning |
| --- | --- |
| `400` | The FHIR server refused the consent write. |
| `401` | The bearer token is missing or invalid. |
| `403` | The session is not a practitioner session, has no project, or its access policy lacks one of the `Consent` interactions. |
| `409` | The write lost a conflict with a concurrent write. Retry. |
| `422` | `termsAndConditionsConsent` is missing or not a boolean. |
| `429` | Too many requests. |
| `503` | The access policy cannot be read for the moment. Retry shortly. |
