---
title: "Follow an extracted link server-side"
method: POST
path: "/v1/messages/{id}/links/follow"
tags: ["messages"]
---

# Follow an extracted link server-side

`POST /v1/messages/{id}/links/follow`

## Request

- Base URL: `https://api.mailfixture.com`
- URL: `https://api.mailfixture.com/v1/messages/{id}/links/follow`
- Auth: HTTP bearer

GETs one of the message's extracted links (default: the first `verify`-classed link), following up to 5 redirects with every hop re-validated against the SSRF guard (https-only, public hosts; 5 s per hop, 15 s total). The target's body is never returned. The final hop's HTTP status is reported in the outcome, not judged — a remote 500 is still a 200 here with `status: 500`.

## Path parameters

- `id` string, uuid, required

## Request body

- FollowRequest: Selects which extracted link to follow. Pass at most one field; with none, the first `verify`-classed link is followed.
  - `class` 'verify' | 'reset' | 'unsubscribe' | 'other': First link of this class.
  - `index` integer: Zero-based index into the extracted links.
  - `url` string: Exact match against a URL in the extracted links.

## Response `200`

The follow outcome.

- FollowOutcome
  - `final_url` string, required: URL of the final, non-redirect response.
  - `ok` boolean, required: True when `status` is 2xx.
  - `redirects` integer, required: Redirect hops followed (max 5).
  - `requested_url` string, required
  - `status` integer, required: HTTP status of the final response — reported, not judged.

## Other responses

- `400`: More than one of `url`/`class`/`index` was passed, or the selected link itself is not followable (guard-refused: non-https, private host, …).
- `401`: Missing bearer token, malformed key, or unknown/revoked/invalid API key.
- `404`: No such message, or no extracted link matches the selector — the detail lists the link classes that do exist.
- `429`: Per-key rate limit exceeded. `Retry-After` says when the next request will be admitted; the RateLimit headers name the bucket that refused (`requests` or `creates`) with `r=0`.
- `500`: Unexpected server error. `detail` is null — internals are never leaked.
- `502`: The remote misbehaved: unreachable, a redirect hop was guard-refused, more than 5 redirects, or the chain exceeded 15 seconds.

---

[API](https://skmtc.dev/mailfixture/apis/mailfixture-api.md) · [All operations](https://skmtc.dev/mailfixture/apis/mailfixture-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailfixture/apis/mailfixture-api/revisions/4ddefe29f6f6?raw)
