---
title: "Redeem a one-click unsubscribe link from an email"
method: POST
path: "/v1/email/unsubscribe"
tags: ["billing"]
---

# Redeem a one-click unsubscribe link from an email

`POST /v1/email/unsubscribe`

## Request

- Base URL: `https://api.hyperresearch.ai`
- URL: `https://api.hyperresearch.ai/v1/email/unsubscribe`
- Auth: none required

Keyless, and idempotent. This is the endpoint named by the `List-Unsubscribe` / `List-Unsubscribe-Post` headers on every non-legal email (RFC 8058): the mail client POSTs it with no session, so the HMAC over user, category and expiry is the whole authentication. Switches that one category off and leaves the other as it stands. A tampered, expired or unknown link is one 403 with one sentence — never a hint about whether the user exists. Legal notices are not switchable and no link is ever minted for one.

## Query parameters

- `u` string, required: The user the link was minted for.
- `c` string, required: The category to switch off: runs, product or onboarding.
- `exp` integer, nullable: Unix seconds the link stops working.
- `sig` string, required: HMAC over the three above.

## Response `200`

The category is off

- EmailPreferences
  - `runs` boolean, required: Emails about your own runs: the report is ready, the run stopped and was refunded, the run is waiting on a question. On by default.
  - `product` boolean, required: Account housekeeping: a card was added, a payment was declined. On by default.
  - `onboarding` boolean, required: Tips for a new account: a welcome when you sign up and, if no run has started, one reminder a day later. Separate from `product`, so turning these off never stops a payment-failed email. On by default.
  - `legal_notices_always` boolean, required: Always true. Notice of a material change to the Terms, of the service being discontinued, or of a security incident is sent whatever these switches say — it is an obligation under the agreement, not a subscription. There is no field to turn it off and no column behind one.

## Other responses

- `400`: Invalid request
- `401`: Authentication failed
- `403`: Invalid or expired link
- `404`: Not found
- `429`: Rate limited or over quota
- `500`: Internal error

---

[API](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api.md) · [All operations](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/revisions/726ef831ebf4?raw)
