Docsary
Markdown Ask Claude Ask ChatGPT
On this page

Redirects

Redirects map an old path on your site to a new one. They are the tool for reorganizing a docs tree without breaking inbound links, search results, or bookmarks.

Redirects belong to the site, not to a version.

Setting them

The endpoint is a whole-map replace. Whatever you send becomes the complete redirect table for the site; anything you leave out is deleted.

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 }

Read the current table back before editing it, so you do not drop entries:

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 }
  ]
}

The field is named source when you write it and source_path when you read it back. A read-modify-write loop has to rename the key. This asymmetry is in the API as it stands.

Sources

A source is a full request path with a leading slash. Leading slashes are normalized to exactly one, so welcome, /welcome, and //welcome all store as /welcome.

Matching is exact — there is no prefix or wildcard matching, and no pattern syntax. Redirecting a whole moved folder means one entry per page.

Two ordering rules matter:

Reserved paths are handled before redirects and cannot be redirected: /search, /assets/*, /robots.txt, /sitemap.xml, /llms.txt, /llms-full.txt, /manifest.webmanifest, /sw.js. A URL under the default version's own prefix — /1.0/anything when 1.0 is the default — is redirected to its clean form before the redirect table is consulted.

A redirect takes precedence over a page that exists at the same path. If a redirect appears to have "deleted" a page, look for a stale entry in the table.

Targets

A target may be:

Anything else is rejected with 400 when you write it: javascript:, data:, vbscript:, file:, mailto:, protocol-relative //host/path, bare fragments like #section, schemeless relative paths like guide/install, and any value containing control characters.

The same check runs again when the redirect is served. A stored target that does not pass is ignored entirely — the request falls through to the normal page lookup or a 404 rather than emitting an unsafe Location header.

Status codes

code accepts 301 or 302. Any other value, including a missing one, stores as 301.

Use 301 for a permanent move — it passes ranking signals and browsers cache it aggressively. Use 302 for a temporary destination, such as a beta path you intend to reclaim.

After a change

A redirect change takes effect on the next request. Browsers that have already cached a 301 will keep following it; that is the nature of a permanent redirect, and it is the reason to be deliberate about the code you choose.

The table can hold as many entries as your plan allows. Writing a longer one is refused outright, leaving the existing table untouched.