On this page
Redirects
Read or replace the site’s complete redirect table. To add or remove an entry, read the table, edit it, then send the full result.
For matching rules and precedence, see Redirects.
All endpoints require an organization API key. :site accepts a slug or an id.
Read the table
GET /v1/sites/:site/redirects
curl -s -H "authorization: Bearer $DOCSARY_KEY" \
"$DOCSARY_API/v1/sites/acme/redirects"
{
"redirects": [
{ "source_path": "/beta", "target": "/", "code": 302 },
{ "source_path": "/old-guide/setup", "target": "/guide/install", "code": 301 },
{ "source_path": "/welcome", "target": "/", "code": 301 }
]
}
Ordered by source path.
Replace the table
PUT /v1/sites/:site/redirects
curl -s -X PUT "$DOCSARY_API/v1/sites/acme/redirects" \
-H "authorization: Bearer $DOCSARY_KEY" \
-H "content-type: application/json" \
-d '{
"redirects": [
{ "source": "/welcome", "target": "/" },
{ "source": "/old-guide/setup", "target": "/guide/install" },
{ "source": "/beta", "target": "/", "code": 302 },
{ "source": "/status", "target": "https://status.acme.com" }
]
}'
{ "count": 4 }
| Field | Type | Required | Notes |
|---|---|---|---|
redirects |
array | yes | The complete table. An empty array clears it. |
redirects[].source |
string | yes | Request path. Leading slashes are normalized to exactly one. |
redirects[].target |
string | yes | Site-relative path or absolute http/https URL. |
redirects[].code |
number | no | 302 for temporary; anything else, including omission, stores as 301. |
This is a replace, not a merge. Every entry not present in the request is deleted. Read the table first and send it back complete.
The write field is source; the read field is source_path. A read-modify-write loop must rename the key between the two calls.
The replacement applies completely or not at all. Previously cached 301 redirects may continue in readers’ browsers.
A table longer than your redirect ceiling is refused with 403 and quota: "redirects_per_site". Nothing is written, and the table you already had stays in place.
Target validation
Every target is checked before anything is written. One bad target fails the entire request; nothing is partially applied.
Accepted:
- A site-relative path beginning with a single
/ - An absolute
http:orhttps:URL
Rejected with 400:
{"error":"unsafe redirect target 'javascript:alert(1)' (allowed: http:, https:, or a /site-relative path)"}
Rejected targets include javascript:, data:, vbscript:, file:, //host/path, #fragment, relative paths without a leading slash, and control characters. Unlike footer links, redirects do not accept mailto:.
An invalid stored target is ignored, and the request continues to the page lookup or a 404.
Other errors
| Response | Cause |
|---|---|
400 {"error":"redirects array required"} |
redirects missing or not an array |
400 {"error":"each redirect needs a string source and target"} |
An entry is null, or source/target is not a string |
404 {"error":"site not found"} |
The site slug or id does not resolve |