Create and manage redirects, custom paths and QR codes from your own code. A small REST API with JSON in and out.
Everything you do in the dashboard for redirects, custom paths and QR codes can also be done through the API: create a redirect when a client signs up, add campaign paths from a script, or generate QR codes for print in bulk.
Every request needs an API key, sent in the Authorization header as a Bearer token.
export R301_KEY="r301_…" # your key, from the dashboard
curl https://api.redirect-301.com/v1/me \ -H "Authorization: Bearer $R301_KEY"
{
"email": "you@example.com",
"plan": "studio",
"maxRedirects": 5
}Treat keys like passwords: keep them on your server, never in a web page or app that others can inspect. If a key leaks, revoke it in the dashboard; it stops working immediately.
Successful calls return 200, 201 (created) or 204 (deleted, no body). Errors always have the same shape: a stable code your code can check, and a human-readable message.
{
"error": {
"code": "plan_limit_reached",
"message": "Your plan allows 5 redirect(s)."
}
}| Status | Code | When |
|---|---|---|
| 400 | validation_error | A field is missing or invalid. The message says which one. |
| 401 | invalid_api_key | No key, or the key is wrong or revoked. |
| 403 | api_not_enabled | Your current plan does not include the API. |
| 403 | account_inactive | The account is inactive (for example, the subscription was cancelled). |
| 404 | not_found | The redirect, path or QR code does not exist in your account. |
| 409 | plan_limit_reached | You already have as many redirects as your plan allows. |
| 409 | host_taken | The domain is already registered. |
| 409 | path_exists | This path already exists on the redirect. |
| 429 | rate_limited | Too many requests: wait for the seconds in the Retry-After header. |
Each key can make 60 requests per minute.
A redirect sends every visit to one of your domains (host) to another URL (redirectTo). It is identified by its host name.
/redirectsList your redirects, with maxRedirects for your plan./redirectsCreate a redirect./redirects/{host}Get one redirect./redirects/{host}Change any of redirectTo, redirectType, followPath, followQueryString./redirects/{host}Delete the redirect, with its paths, QR codes and stats./redirects/{host}/statusDNS and certificate state (see below).| Field | Type | Description |
|---|---|---|
host | string | The domain that redirects, like old-brand.com. Required on create; can’t be changed. |
redirectTo | string | Full destination URL (http:// or https://), on a different domain. Required on create. |
redirectType | number | 301 (permanent, the default) or 302 (temporary). |
followPath | boolean | Keep the visited path: old-brand.com/about → new-brand.com/about. Default true. |
followQueryString | boolean | Keep the query string (?utm_source=…). Default true. |
status | string | not_configured (DNS not pointing yet), pending (certificate being issued), active, disabled or error. Read only. |
dns | object | The DNS record to create at your domain provider. Read only. |
curl -X POST https://api.redirect-301.com/v1/redirects \
-H "Authorization: Bearer $R301_KEY" \
-H "Content-Type: application/json" \
-d '{"host": "old-brand.com", "redirectTo": "https://new-brand.com"}'{
"host": "old-brand.com",
"redirectTo": "https://new-brand.com",
"redirectType": 301,
"followPath": true,
"followQueryString": true,
"status": "not_configured",
"dns": { "type": "A", "name": "old-brand.com", "value": "18.215.89.131" },
"certificateExpiresAt": null,
"errorMessage": null,
"createdAt": "2026-09-26T14:02:11"
}Then create the A record from dns at your domain provider. As soon as the domain points to us, we issue the HTTPS certificate and the status moves to pending, then active. Call the status endpoint to check the DNS and to start the certificate right away:
curl https://api.redirect-301.com/v1/redirects/old-brand.com/status \ -H "Authorization: Bearer $R301_KEY"
{
"host": "old-brand.com",
"status": "pending",
"dns": {
"expected": { "type": "A", "name": "old-brand.com", "value": "18.215.89.131" },
"resolved": ["18.215.89.131"],
"pointing": true
},
"certificate": { "expiresAt": null },
"errorMessage": null
}curl -X PATCH https://api.redirect-301.com/v1/redirects/old-brand.com \
-H "Authorization: Bearer $R301_KEY" \
-H "Content-Type: application/json" \
-d '{"redirectType": 302, "followPath": false}'A custom path sends one path of your domain somewhere specific, like old-brand.com/promo → new-brand.com/summer-sale. Other paths keep following the redirect’s main rule.
/redirects/{host}/pathsList the redirect’s paths./redirects/{host}/pathsCreate a path./redirects/{host}/paths/{id}Change any field./redirects/{host}/paths/{id}Delete the path and the QR codes that point to it.| Field | Type | Description |
|---|---|---|
fromPath | string | The path on your domain, like /promo. The leading / is added if missing; paths are case-insensitive and unique per redirect. Required. |
redirectTo | string | Where it goes. A path on the redirect’s destination (/summer-sale), or a full URL when absolute is true. Required. |
absolute | boolean | true to send the path to any URL, even on another domain. Default false. |
statusCode | number | 301 (default), 302, 307 or 308. |
curl -X POST https://api.redirect-301.com/v1/redirects/old-brand.com/paths \
-H "Authorization: Bearer $R301_KEY" \
-H "Content-Type: application/json" \
-d '{"fromPath": "/promo", "redirectTo": "/summer-sale"}'{
"id": 42,
"fromPath": "/promo",
"redirectTo": "/summer-sale",
"absolute": false,
"statusCode": 301,
"createdAt": "2026-09-26T14:05:40"
}A QR code opens the redirect’s domain, or one of its custom paths. Every QR code has its own url with a ?_qr= marker, so its scans are counted separately in your stats; the marker is removed before the visitor is redirected.
/redirects/{host}/qr-codesList the redirect’s QR codes./redirects/{host}/qr-codesCreate a QR code./redirects/{host}/qr-codes/{id}Change any field. Send "pathId": null to point it back to the domain./redirects/{host}/qr-codes/{id}Delete the QR code./redirects/{host}/qr-codes/{id}/imageThe image: format=png (default) or svg, size in pixels from 64 to 2048 (default 512).| Field | Type | Description |
|---|---|---|
label | string | Your name for it, like “Flyer A5”. Required. |
pathId | number | The custom path it opens. Omit (or null) for the domain itself. |
color | string | Hex color of the code, like #0A0E14 (the default). |
format | string | Preferred download format in the dashboard: png, svg or pdf. |
url | string | What the QR code encodes. Read only. |
curl -X POST https://api.redirect-301.com/v1/redirects/old-brand.com/qr-codes \
-H "Authorization: Bearer $R301_KEY" \
-H "Content-Type: application/json" \
-d '{"label": "Flyer A5", "pathId": 42, "color": "#0A0E14"}'{
"id": 7,
"label": "Flyer A5",
"pathId": 42,
"color": "#0A0E14",
"format": "png",
"url": "https://old-brand.com/promo?_qr=7",
"imageUrl": "/v1/redirects/old-brand.com/qr-codes/7/image",
"createdAt": "2026-09-26T14:07:02"
}curl -o flyer.png "https://api.redirect-301.com/v1/redirects/old-brand.com/qr-codes/7/image?format=png&size=1024" \ -H "Authorization: Bearer $R301_KEY"
Images are generated on request and never expire, so you can re-download them any time. Once a QR code is printed, keep it: a printed code still redirects after you delete it, but its scans are no longer counted, and if you delete its path it opens the redirect’s main destination instead.
Feel free to reach out to us with any questions. We're here to help! Scan the QR code or click the button below to join our WhatsApp group.
Open WhatsApp →