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

# Unsubscribe a contact

> POST /v1/contacts/{id}/unsubscribe — opt a contact out, setting subscribed to false and stamping unsubscribedAt.

A convenience flip that opts a contact out: sets subscribed to false and stamps the moment they unsubscribed.

**`POST /v1/contacts/{id}/unsubscribe`**

## Path parameters

<ParamField body="id" type="string" required>
  The contact id to opt out.
</ParamField>

This endpoint takes no request body.

<Note>
  **App-level signal, not a delivery block.** Unsubscribing flips the contact's `subscribed` flag — an app-level signal you honor in your own sending logic. It does not add the address to the [suppression list](/api-reference/suppressions/list). To hard-block delivery, add a suppression as well.
</Note>

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.drin.run/v1/contacts/ct_7Yh2Lp/unsubscribe \
    -H "Authorization: Bearer $DRIN_API_KEY"
  ```

  ```typescript Node.js theme={null}
  import { DrinClient } from "@drin00/sdk";

  const drin = new DrinClient({ apiKey: process.env.DRIN_API_KEY });

  const contact = await drin.contacts.unsubscribe("ct_7Yh2Lp");
  console.log(contact.subscribed);      // false
  console.log(contact.unsubscribedAt);  // ISO timestamp
  ```
</CodeGroup>

## Response

Returns `200 OK` with the contact, now showing `subscribed: false` and a non-null `unsubscribedAt`. The call is idempotent. An unknown id returns `404 not_found`.

```json 200 OK theme={null}
{
  "id": "ct_7Yh2Lp",
  "email": "ada@example.com",
  "firstName": "Ada",
  "lastName": "Lovelace",
  "subscribed": false,
  "unsubscribedAt": "2026-06-02T18:12:40.000Z",
  "metadata": { "plan": "pro" },
  "createdAt": "2026-06-02T17:30:00.000Z",
  "updatedAt": "2026-06-02T18:12:40.000Z"
}
```
