---
title: The REST API
description: "The frwrd.to REST API: base URL, authorisation, one curl example for each main call, the Bit.ly compatible /v4 subset, rate limits and errors."
theme: { accent: "#1f6feb", background: light }
translations: { de: de/hilfe-api }
---

# The REST API

The base URL is `https://api.frwrd.to`. Every call except creating and
recovering a workspace takes your workspace key as a bearer token:

```
Authorization: Bearer fw_...
```

The examples below read the key from `$FRWRD_KEY`. Bodies are JSON unless
the example says otherwise.

## Links

Create a short link:

```
curl -X POST https://api.frwrd.to/v1/links -H "Authorization: Bearer $FRWRD_KEY" -H "Content-Type: application/json" -d '{"long_url":"https://example.com/a/long/address","title":"Example"}'
```

The answer has the short `link`, its `hash` and the addresses of its QR
code. Only `http` and `https` targets are accepted. You can also send
`tags`, `utm` and, on a verified workspace, your own `hash`.

List links, newest first (`limit` up to 200, and `offset`):

```
curl "https://api.frwrd.to/v1/links?limit=50" -H "Authorization: Bearer $FRWRD_KEY"
```

Numbers for one link, by default the last 30 days (`since` and `until` take
a date such as 2026-10-01, at most 366 days apart):

```
curl "https://api.frwrd.to/v1/links/aB3xZ9/stats?since=2026-10-01" -H "Authorization: Bearer $FRWRD_KEY"
```

The answer gives the total, the split by channel (`link` for a direct click,
`qr` for a scan, `page` for a click on a bio page) and the numbers per day.

The QR code, as PNG or SVG (`size` from 128 to 2048):

```
curl "https://api.frwrd.to/v1/links/aB3xZ9/qr.png?size=512" -H "Authorization: Bearer $FRWRD_KEY" -o code.png
```

To change a link, send `PATCH /v1/links/{hash}` with any of `long_url`,
`title`, `tags` and `archived`. `DELETE /v1/links/{hash}` archives it: it
stops redirecting, and its numbers stay.

## Pages

A page is a Markdown document with a short header. You save the whole
document in one call. The path `-` is the root page; a page in another
language lives under its language code, and the slash is written `%2F`, as
in `de%2Fhilfe`.

```
curl -X PUT https://api.frwrd.to/v1/pages/hello -H "Authorization: Bearer $FRWRD_KEY" -H "Content-Type: text/markdown" --data-binary @hello.md
```

Every link in the document becomes a short link of your workspace. To read
a page back as Markdown, send `Accept: text/markdown`; the answer carries
an `ETag`. Send it back as `If-Match` when you save, and the call fails with
`412` if someone changed the page meanwhile.

Views of a page and clicks on each of its links:

```
curl "https://api.frwrd.to/v1/pages/hello/stats" -H "Authorization: Bearer $FRWRD_KEY"
```

`GET /v1/pages` lists your pages, `GET /v1/pages/{path}/versions` shows the
history and `DELETE /v1/pages/{path}` archives a page.

## Bit.ly compatible /v4

Tools that speak Bit.ly's v4 API can point at `https://api.frwrd.to/v4` and
use your workspace key as the token. These calls exist, with Bit.ly's
answers, timestamps and error messages:

- `POST /v4/shorten`
- `POST /v4/expand`
- `PATCH /v4/bitlinks/frwrd.to/{hash}`
- `GET /v4/bitlinks/frwrd.to/{hash}/clicks/summary`

Anything else of Bit.ly's is not served. A spent link quota answers `429`
with `MONTHLY_LIMIT_EXCEEDED`.

## Limits and errors

- Before it checks your key, the API allows 20 requests per second from one address (bursts of 60). After that, 10 per second for each workspace (bursts of 30). Creating or recovering workspaces is limited to 5 per minute per address.
- Over a limit, the answer is `429` with the code `rate_limited`, and a `Retry-After` header says when to try again.
- Errors on `/v1` are JSON: `{"error":{"code":"...","message":"..."}}`. Branch on `code`: `invalid_body`, `missing_credentials`, `invalid_credentials`, `not_found`, `conflict`, `precondition_failed`, `quota_exceeded`, `not_verified`, `rate_limited` or `internal_error`.

The full contract is an OpenAPI document that lives with the source code,
which is not public yet. Until then, the calls above, the MCP tool
descriptions and `frwrd.to/llms.txt` describe the API.

- [Back to help](/@frwrd.to/help)
