{"openapi":"3.1.0","info":{"title":"RedirHub","version":"1.0.0"},"servers":[{"url":"https://api.redirhub.com/v1","description":"Production"}],"tags":[{"name":"Links","description":"List and create every kind of link in one place: short links, QR codes, redirects and website migrations."},{"name":"Redirects","description":"Deprecated: use Links, which creates and manages redirects together with every other kind of link."},{"name":"Short Links","description":"Deprecated: use Links, which creates and manages short links together with every other kind of link."},{"name":"Bulk Operations","description":"Import, export, update, and delete redirects and short links in bulk."},{"name":"Hostnames","description":"Connect hostnames, manage their configuration, and select a routing cluster."},{"name":"Workspace","description":"Workspace details and subscriptions."},{"name":"Account & Reference","description":"Account settings plus shared reference and recommendation endpoints."}],"security":[{"http":[]}],"paths":{"/links":{"get":{"operationId":"links.index","tags":["Links"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"A cursor-paginated page of every record of the workspace. Narrow it with `filter[handler]` (comma-separated), `filter[status]` (`active` or `paused`), `filter[dns_correct]`, `filter[host]` and `filter[path]` (`/` for the root page of a hostname, `*` for the record that answers every other path), and `filter[file]` for the record with that exact short link or source URL (`go.example.com/menu`, the value of the Analytics link filter). Order it with `sort`: `-id` (newest, the default), `-updated_at` (recently updated), `-total_clicks` (most clicks) or `total_clicks` (fewest clicks). `total_clicks` counts every click since the record was created. Follow `meta.cursor.next` for the next page.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_7bXmR4","handler":"qr","host":"go.example.com","alias":"menu","url":"go.example.com/menu","https":true,"file":"go.example.com/menu","destination":"https://example.com/restaurant/menu","destinations":["https://example.com/restaurant/menu"],"destination_routing":"random","plugins":[],"has_password":false,"total_clicks":2410,"type":"302","title":"Table tent menu","description":null,"note":"Spring campaign landing page, requested by the marketing team (ticket MKT-42)","status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":{"theme":"light","color":"#181D27","logo":false,"show_url":true,"margin":"m"},"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["print"],"created_by":"user_4dRt2X","creator":{"id":"user_4dRt2X","name":"Mia Chen"},"created_via":"dashboard","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"meta":{"cursor":{"current":null,"prev":null,"next":null,"count":1}}}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"handler":{"type":"string"},"host":{"type":"string"},"alias":{"type":["string","null"]},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"total_clicks":{"type":"integer","minimum":0},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"integration_status":{"type":["string","null"],"enum":["connected","waiting","sync_stopped",null]},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"pending_options":{"type":["array","null"],"items":{"type":"string","enum":["forward_path","plugins","is_notify","is_switch_unbroken_destination","destinations","destination_routing","type","wildcard"]}},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"creator":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","handler","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","total_clicks","type","title","description","note","status","integration_status","paused_by","pending_options","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","creator","created_via","created_at","updated_at","expired_at"]}},"meta":{"type":"object","properties":{"cursor":{"type":"object","properties":{"current":{"type":"null"},"prev":{"type":["string","null"]},"next":{"type":["string","null"]},"count":{"type":"integer"}},"required":["current","prev","next","count"]}},"required":["cursor"]}},"required":["data","meta"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"post":{"operationId":"links.store","tags":["Links"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreLinksRequest"}}}},"responses":{"200":{"description":"The records created by this request. The payload is always a collection, even for a single record.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_7bXmR4","handler":"qr","host":"go.example.com","alias":"menu","url":"go.example.com/menu","https":true,"file":"go.example.com/menu","destination":"https://example.com/restaurant/menu","destinations":["https://example.com/restaurant/menu"],"destination_routing":"random","plugins":[],"has_password":false,"total_clicks":2410,"type":"302","title":"Table tent menu","description":null,"note":"Spring campaign landing page, requested by the marketing team (ticket MKT-42)","status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":{"theme":"light","color":"#181D27","logo":false,"show_url":true,"margin":"m"},"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["print"],"created_by":"user_4dRt2X","creator":{"id":"user_4dRt2X","name":"Mia Chen"},"created_via":"dashboard","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"handler":{"type":"string"},"host":{"type":"string"},"alias":{"type":["string","null"]},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"total_clicks":{"type":"integer","minimum":0},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"integration_status":{"type":["string","null"],"enum":["connected","waiting","sync_stopped",null]},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"pending_options":{"type":["array","null"],"items":{"type":"string","enum":["forward_path","plugins","is_notify","is_switch_unbroken_destination","destinations","destination_routing","type","wildcard"]}},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"creator":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","handler","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","total_clicks","type","title","description","note","status","integration_status","paused_by","pending_options","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","creator","created_via","created_at","updated_at","expired_at"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/links/count":{"get":{"operationId":"links.count","tags":["Links"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"Record totals for the current filter: all of them, the paused ones, the ones whose hostname is not connected yet (its DNS does not point to RedirHub, or an integration's check path has not proven it yet), and the ones with no clicks in the last four weeks (this week included). Totals are kept for a minute; for a workspace with 10,000 links or more, older totals are returned at once with `refreshing` true while fresh ones are computed, so ask again a few seconds later. The first time such a workspace is counted, only `total` comes back, with `refreshing` true, until the rest is computed.","content":{"application/json":{"schema":{"type":"object","examples":[{"total":1556,"paused":12,"dns_issue":3,"no_clicks":204,"refreshing":false}],"properties":{"total":{"type":"integer","minimum":0},"paused":{"type":"integer","minimum":0},"dns_issue":{"type":"integer","minimum":0},"no_clicks":{"type":"integer","minimum":0},"refreshing":{"type":"boolean"}},"required":["total","refreshing"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/links/facets":{"get":{"operationId":"links.facets","tags":["Links"],"parameters":[{"name":"hosts_search","in":"query","schema":{"type":["string","null"],"maxLength":255}},{"name":"hosts_limit","in":"query","schema":{"type":["integer","null"],"minimum":1,"maximum":200}},{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"Counts per value over the records the current filter matches, for suggested filters: the largest domains (20 unless `hosts_limit` says otherwise, up to 200, narrowed by `hosts_search`) and how many domains there are in all, the 20 largest tags, untagged records, QR codes (created as one, or links that also have one), records per kind (`link`, `qr`, `redirect`, `migration`, and `html` for HTML pages), health (paused, DNS issue, no clicks in the last four weeks), records created in the last 7 and 30 days, and when a record was last created or changed (`last_changed_at`, null without records). Counts are kept for a minute; for a workspace with 10,000 links or more, older counts are returned at once with `refreshing` true while fresh ones are computed, so ask again a few seconds later. The first time such a workspace is counted, only `total` comes back, with `refreshing` true, until the rest is computed.","content":{"application/json":{"schema":{"type":"object","examples":[{"total":1556,"hosts":[{"value":"acme.co","count":812},{"value":"shop.acme.com","count":402}],"hosts_total":38,"tags":[{"slug":"summer-2026","name":"summer-2026","count":212}],"untagged":930,"qr":{"qr_codes":24,"links_with_qr":6},"kinds":{"link":1120,"qr":24,"redirect":380,"migration":32,"html":3},"health":{"paused":12,"dns_issue":3,"no_clicks":204},"created":{"last_7_days":18,"last_30_days":64},"last_changed_at":"2026-09-30T14:12:00+00:00","refreshing":false}],"properties":{"total":{"type":"integer","minimum":0},"hosts":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["value","count"]}},"hosts_total":{"type":"integer","minimum":0},"tags":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["slug","name","count"]}},"untagged":{"type":"integer","minimum":0},"qr":{"type":"object","properties":{"qr_codes":{"type":"integer","minimum":0},"links_with_qr":{"type":"integer","minimum":0}},"required":["qr_codes","links_with_qr"]},"kinds":{"type":"object","properties":{"link":{"type":"integer","minimum":0},"qr":{"type":"integer","minimum":0},"redirect":{"type":"integer","minimum":0},"migration":{"type":"integer","minimum":0},"html":{"type":"integer","minimum":0}},"required":["link","qr","redirect","migration","html"]},"health":{"type":"object","properties":{"paused":{"type":"integer","minimum":0},"dns_issue":{"type":"integer","minimum":0},"no_clicks":{"type":"integer","minimum":0}},"required":["paused","dns_issue","no_clicks"]},"created":{"type":"object","properties":{"last_7_days":{"type":"integer","minimum":0},"last_30_days":{"type":"integer","minimum":0}},"required":["last_7_days","last_30_days"]},"last_changed_at":{"type":["string","null"]},"refreshing":{"type":"boolean"}},"required":["total","refreshing"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/links/filter-pins":{"get":{"operationId":"links.filterPins","tags":["Links"],"responses":{"200":{"description":"The suggested filters the workspace pinned to its Links list, in order. Each pin is a kind (`host`, `tag`, `qr`, `type`, `health` or `created`) and its value.","content":{"application/json":{"schema":{"type":"object","examples":[{"pins":[{"kind":"host","value":"acme.co"},{"kind":"tag","value":"print"}]}],"properties":{"pins":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"value":{"type":"string"}},"required":["kind","value"]}}},"required":["pins"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"put":{"operationId":"links.updateFilterPins","tags":["Links"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilterPinsRequest"}}}},"responses":{"200":{"description":"Replaces the workspace's pinned filters with `pins` (at most 10; duplicates are dropped) and returns them.","content":{"application/json":{"schema":{"type":"object","examples":[{"pins":[{"kind":"host","value":"acme.co"}]}],"properties":{"pins":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"value":{"type":"string"}},"required":["kind","value"]}}},"required":["pins"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/links/{id}/history":{"get":{"operationId":"links.history","tags":["Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The changes made to the record after it was created, newest first, one entry per change. `old` and `new` hold only the fields that changed, keyed by field: `destination` (every destination, the primary one first; null while the record serves HTML), `utm`, `type` and `status` (`active` / `paused`). `actor.name` is who made the change as it read then: the user's name, or the API token's name when `source` is `api`. `meta.cursor.total` counts every change of the record. Reading the changes is the plan's audit log, from Pro up (feature `security.audit`); without it `data` is empty while `meta.cursor.total` still counts the changes, so the dashboard can show how many there are next to an upgrade prompt. Follow `meta.cursor.next` for the next page.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":42,"old":{"destination":["https://example.com/restaurant/menu-summer"],"utm":null},"new":{"destination":["https://example.com/restaurant/menu-fall"],"utm":{"source":"print"}},"actor":{"id":"user_4dRt2X","name":"zapier-sync"},"source":"api","created_at":"2026-09-01T08:40:00.000000Z"}],"meta":{"cursor":{"current":null,"prev":null,"next":null,"count":1,"total":4}}}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"old":{"type":"object","properties":{"destination":{"type":["array","null"],"items":{"type":"string"}},"utm":{"type":["object","null"],"additionalProperties":{"type":"string"}},"type":{"type":["string","null"]},"status":{"type":"string"},"password":{"type":"boolean"},"note":{"type":["string","null"]}}},"new":{"type":"object","properties":{"destination":{"type":["array","null"],"items":{"type":"string"}},"utm":{"type":["object","null"],"additionalProperties":{"type":"string"}},"type":{"type":["string","null"]},"status":{"type":"string"},"password":{"type":"boolean"},"note":{"type":["string","null"]}}},"actor":{"type":"object","properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["id","name"]},"source":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"}},"required":["id","old","new","actor","source","created_at"]}},"meta":{"type":"object","properties":{"cursor":{"type":"object","properties":{"current":{"type":"null"},"prev":{"type":["string","null"]},"next":{"type":["string","null"]},"count":{"type":"integer"},"total":{"type":"integer"}},"required":["current","prev","next","count","total"]}},"required":["cursor"]}},"required":["data","meta"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/links/{id}/qr":{"get":{"operationId":"links.qr","description":"The code the dashboard draws for the link: its saved QR style (or the default one), the\nworkspace logo in the centre when the style asks for it, and the readable link under it.\nIt encodes the link with `?utm_source=qr`, so scans are counted apart from clicks.","summary":"Get a link's QR code","tags":["Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","description":"The image format. Default: `svg`.","schema":{"type":"string","enum":["svg","png"]}},{"name":"width","in":"query","description":"Width of a PNG in pixels. Default: `1024`.","schema":{"type":"integer","enum":["512","1024","2048"]}}],"responses":{"200":{"description":"The QR code, as SVG by default or as PNG with `format=png`.","content":{"image/svg+xml":{"schema":{"type":"string"}},"image/png":{"schema":{"type":"string","format":"binary"}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/links/{id}":{"get":{"operationId":"links.show","tags":["Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested record, whatever its handler.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_7bXmR4","handler":"qr","host":"go.example.com","alias":"menu","url":"go.example.com/menu","https":true,"file":"go.example.com/menu","destination":"https://example.com/restaurant/menu","destinations":["https://example.com/restaurant/menu"],"destination_routing":"random","plugins":[],"has_password":false,"total_clicks":2410,"type":"302","title":"Table tent menu","description":null,"note":"Spring campaign landing page, requested by the marketing team (ticket MKT-42)","status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":{"theme":"light","color":"#181D27","logo":false,"show_url":true,"margin":"m"},"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["print"],"created_by":"user_4dRt2X","creator":{"id":"user_4dRt2X","name":"Mia Chen"},"created_via":"dashboard","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"handler":{"type":"string"},"host":{"type":"string"},"alias":{"type":["string","null"]},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"total_clicks":{"type":"integer","minimum":0},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"integration_status":{"type":["string","null"],"enum":["connected","waiting","sync_stopped",null]},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"pending_options":{"type":["array","null"],"items":{"type":"string","enum":["forward_path","plugins","is_notify","is_switch_unbroken_destination","destinations","destination_routing","type","wildcard"]}},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"creator":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","handler","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","total_clicks","type","title","description","note","status","integration_status","paused_by","pending_options","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","creator","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"put":{"operationId":"links.update","tags":["Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLinksRequest"}}}},"responses":{"200":{"description":"The updated record. Its handler and source URL never change; short links also take a partial `qr` style, or `null` to remove the QR code. A change to its destinations, UTM parameters, redirect type, status, password or note is added to its history.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_7bXmR4","handler":"qr","host":"go.example.com","alias":"menu","url":"go.example.com/menu","https":true,"file":"go.example.com/menu","destination":"https://example.com/restaurant/menu","destinations":["https://example.com/restaurant/menu"],"destination_routing":"random","plugins":[],"has_password":false,"total_clicks":2410,"type":"302","title":"Table tent menu","description":null,"note":"Spring campaign landing page, requested by the marketing team (ticket MKT-42)","status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":{"theme":"light","color":"#181D27","logo":false,"show_url":true,"margin":"m"},"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["print"],"created_by":"user_4dRt2X","creator":{"id":"user_4dRt2X","name":"Mia Chen"},"created_via":"dashboard","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"handler":{"type":"string"},"host":{"type":"string"},"alias":{"type":["string","null"]},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"total_clicks":{"type":"integer","minimum":0},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"integration_status":{"type":["string","null"],"enum":["connected","waiting","sync_stopped",null]},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"pending_options":{"type":["array","null"],"items":{"type":"string","enum":["forward_path","plugins","is_notify","is_switch_unbroken_destination","destinations","destination_routing","type","wildcard"]}},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"creator":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","handler","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","total_clicks","type","title","description","note","status","integration_status","paused_by","pending_options","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","creator","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"delete":{"operationId":"links.destroy","description":"The link's change history is deleted with it. A redirect saved before its plan takes its\ndomain with it while nothing else uses the domain and its DNS was never connected, so the\ndomain counts against the plan no longer.","summary":"Delete a link","tags":["Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No content","headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/redirect":{"post":{"operationId":"redirect.store","description":"**Deprecated since 2026-10-04.** Use `POST /v1/links` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectRequest"}}}},"responses":{"200":{"description":"The redirects created by this request. A single call can create several redirects at once, so the payload is always a collection.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_9wPqK3","tld":"example.com","host":"go.example.com","url":"go.example.com/summer-sale","https":true,"file":"go.example.com/summer-sale","destination":"https://shop.example.com/summer-sale","destinations":["https://shop.example.com/summer-sale","https://shop.example.com/backup"],"destination_routing":"random","plugins":["nobot"],"type":null,"title":null,"description":null,"note":null,"status":"active","forward_path":true,"forward_query":false,"utm":{"source":"newsletter"},"monitor":null,"is_notify":null,"is_switch_unbroken_destination":null,"tags":[],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"tld":{"type":["string","null"]},"host":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":["array","null"],"items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"]},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","tld","host","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"get":{"operationId":"redirect.index","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links?filter[handler]=redirect,migration` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"A cursor-paginated page of redirects. Follow `meta.cursor.next` for the next page.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_9wPqK3","tld":"example.com","host":"go.example.com","url":"go.example.com/summer-sale","https":true,"file":null,"destination":"https://shop.example.com/summer-sale","destinations":["https://shop.example.com/summer-sale"],"destination_routing":"first","plugins":["nobot"],"type":"301","title":"Summer sale","description":null,"note":null,"status":"active","forward_path":true,"forward_query":true,"utm":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["campaign"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"meta":{"cursor":{"current":null,"prev":null,"next":null,"count":1}}}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"tld":{"type":["string","null"]},"host":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":["array","null"],"items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","tld","host","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}},"meta":{"type":"object","properties":{"cursor":{"type":"object","properties":{"current":{"type":"null"},"prev":{"type":["string","null"]},"next":{"type":["string","null"]},"count":{"type":"integer"}},"required":["current","prev","next","count"]}},"required":["cursor"]}},"required":["data","meta"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/redirect/count":{"get":{"operationId":"redirect.count","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/count?filter[handler]=redirect,migration` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"Redirect totals for the current filter.","content":{"application/json":{"schema":{"type":"object","examples":[{"total":128,"paused":4}],"properties":{"total":{"type":"integer","minimum":0},"paused":{"type":"integer","minimum":0}},"required":["total","paused"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/redirect/tags":{"get":{"operationId":"redirect.tags","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/facets` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"responses":{"200":{"description":"Tags used by the workspace, with the number of records carrying each one.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"slug":"tag-redacted-1","name":"Tag redacted 1","count":41},{"slug":"tag-redacted-2","name":"Tag redacted 2","count":41},{"slug":"tag-redacted-3","name":"Tag redacted 3","count":40},{"slug":"tag-redacted-4","name":"Tag redacted 4","count":40},{"slug":"tag-redacted-5","name":"Tag redacted 5","count":40},{"slug":"tag-redacted-6","name":"Tag redacted 6","count":40},{"slug":"tag-redacted-7","name":"Tag redacted 7","count":29},{"slug":"tag-redacted-8","name":"Tag redacted 8","count":2},{"slug":"tag-redacted-9","name":"Tag redacted 9","count":1},{"slug":"tag-redacted-10","name":"Tag redacted 10","count":1}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["slug","name","count"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/redirect/{id}":{"get":{"operationId":"redirect.show","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested redirect.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_9wPqK3","tld":"example.com","host":"go.example.com","url":"go.example.com/summer-sale","https":true,"file":null,"destination":"https://shop.example.com/summer-sale","destinations":["https://shop.example.com/summer-sale"],"destination_routing":"first","plugins":["nobot"],"type":"301","title":"Summer sale","description":null,"note":null,"status":"active","forward_path":true,"forward_query":true,"utm":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["campaign"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"tld":{"type":["string","null"]},"host":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":["array","null"],"items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","tld","host","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"delete":{"operationId":"redirect.destroy","description":"**Deprecated since 2026-10-04.** Use `DELETE /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No content","headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"put":{"operationId":"redirect.update","description":"**Deprecated since 2026-10-04.** Use `PUT /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Redirects"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectRequest"}}}},"responses":{"200":{"description":"The updated redirect.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_9wPqK3","tld":"example.com","host":"go.example.com","url":"go.example.com/summer-sale","https":true,"file":null,"destination":"https://shop.example.com/summer-sale","destinations":["https://shop.example.com/summer-sale"],"destination_routing":"first","plugins":["nobot"],"type":"301","title":"Summer sale","description":null,"note":null,"status":"active","forward_path":true,"forward_query":true,"utm":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["campaign"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"tld":{"type":["string","null"]},"host":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":["array","null"],"items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","tld","host","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/link":{"post":{"operationId":"link.store","description":"**Deprecated since 2026-10-04.** Use `POST /v1/links` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLinkRequest"}}}},"responses":{"200":{"description":"The short links created by this request. The payload is always a collection, even for a single link.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_7bXmR4","host":"go.example.com","alias":"docs","url":"go.example.com/docs","https":true,"file":"go.example.com/docs","destination":"https://docs.example.com/getting-started","destinations":["https://docs.example.com/getting-started"],"destination_routing":"random","plugins":["nobot"],"type":null,"title":null,"description":null,"note":null,"status":"active","forward_path":null,"forward_query":null,"utm":null,"qr":null,"monitor":null,"is_notify":null,"is_switch_unbroken_destination":null,"tags":[],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"alias":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":["string","null"]},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"]},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":["integer","null"]},"is_switch_unbroken_destination":{"type":["integer","null"]},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"get":{"operationId":"link.index","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links?filter[handler]=short-url,qr` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"A cursor-paginated page of short links. Follow `meta.cursor.next` for the next page.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"link_7bXmR4","host":"go.example.com","alias":"docs","url":"go.example.com/docs","https":true,"file":null,"destination":"https://docs.example.com/getting-started","destinations":["https://docs.example.com/getting-started"],"destination_routing":"first","plugins":[],"type":"301","title":"Docs","description":null,"note":null,"status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["docs"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"meta":{"cursor":{"current":null,"prev":null,"next":null,"count":1}}}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"alias":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}},"meta":{"type":"object","properties":{"cursor":{"type":"object","properties":{"current":{"type":"null"},"prev":{"type":["string","null"]},"next":{"type":["string","null"]},"count":{"type":"integer"}},"required":["current","prev","next","count"]}},"required":["cursor"]}},"required":["data","meta"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/link/count":{"get":{"operationId":"link.count","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/count?filter[handler]=short-url,qr` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","description":"Filter results by one or more fields.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"Short link totals for the current filter.","content":{"application/json":{"schema":{"type":"object","examples":[{"total":42,"paused":1}],"properties":{"total":{"type":"integer","minimum":0},"paused":{"type":"integer","minimum":0}},"required":["total","paused"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/link/tags":{"get":{"operationId":"link.tags","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/facets` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"responses":{"200":{"description":"Tags used by the workspace, with the number of records carrying each one.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"slug":"tag-redacted-1","name":"Tag redacted 1","count":41},{"slug":"tag-redacted-2","name":"Tag redacted 2","count":41},{"slug":"tag-redacted-3","name":"Tag redacted 3","count":40},{"slug":"tag-redacted-4","name":"Tag redacted 4","count":40},{"slug":"tag-redacted-5","name":"Tag redacted 5","count":40},{"slug":"tag-redacted-6","name":"Tag redacted 6","count":40},{"slug":"tag-redacted-7","name":"Tag redacted 7","count":29},{"slug":"tag-redacted-8","name":"Tag redacted 8","count":2},{"slug":"tag-redacted-9","name":"Tag redacted 9","count":1},{"slug":"tag-redacted-10","name":"Tag redacted 10","count":1}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["slug","name","count"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/link/{id}":{"get":{"operationId":"link.show","description":"**Deprecated since 2026-10-04.** Use `GET /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested short link.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_7bXmR4","host":"go.example.com","alias":"docs","url":"go.example.com/docs","https":true,"file":null,"destination":"https://docs.example.com/getting-started","destinations":["https://docs.example.com/getting-started"],"destination_routing":"first","plugins":[],"type":"301","title":"Docs","description":null,"note":null,"status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["docs"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"host":{"type":"string"},"alias":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"delete":{"operationId":"link.destroy","description":"**Deprecated since 2026-10-04.** Use `DELETE /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No content","headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"put":{"operationId":"link.update","description":"**Deprecated since 2026-10-04.** Use `PUT /v1/links/{id}` instead. Responses carry a `Deprecation` header and a `Link` header with `rel=\"successor-version\"`.","deprecated":true,"tags":["Short Links"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLinkRequest"}}}},"responses":{"200":{"description":"The updated short link.","content":{"application/json":{"schema":{"type":"object","examples":[{"id":"link_7bXmR4","host":"go.example.com","alias":"docs","url":"go.example.com/docs","https":true,"file":null,"destination":"https://docs.example.com/getting-started","destinations":["https://docs.example.com/getting-started"],"destination_routing":"first","plugins":[],"type":"301","title":"Docs","description":null,"note":null,"status":"active","forward_path":false,"forward_query":true,"utm":null,"qr":null,"monitor":null,"is_notify":0,"is_switch_unbroken_destination":0,"tags":["docs"],"created_by":"user_4dRt2X","created_via":"api","created_at":"2026-07-14T09:30:00.000000Z","updated_at":"2026-07-14T09:30:00.000000Z","expired_at":null}],"properties":{"id":{"type":"string"},"host":{"type":"string"},"alias":{"type":"string"},"url":{"type":"string"},"https":{"type":"boolean"},"file":{"type":["string","null"]},"destination":{"type":"string"},"destinations":{"type":"array","items":{"type":"string"}},"destination_routing":{"anyOf":[{"$ref":"#/components/schemas/DestinationRouting"},{"type":"null"}]},"plugins":{"type":"array","items":{"type":"string"}},"has_password":{"type":"boolean"},"type":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"]},"note":{"type":["string","null"]},"status":{"type":"string"},"paused_by":{"type":["string","null"],"enum":["user","activation","payment","lapsed","limit","plan","visits",null]},"forward_path":{"type":"boolean"},"forward_query":{"type":"boolean"},"utm":{"type":["object","null"],"properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}}},"qr":{"type":["object","null"],"properties":{"theme":{"type":"string"},"color":{"type":"string"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string"}},"required":["theme","color","logo","show_url","margin"]},"monitor":{"type":["string","null"]},"is_notify":{"type":"integer"},"is_switch_unbroken_destination":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}},"created_by":{"type":["string","null"]},"created_via":{"type":"string"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"expired_at":{"type":["string","null"],"format":"date-time"}},"required":["id","host","alias","url","https","file","destination","destinations","destination_routing","plugins","has_password","type","title","description","note","status","paused_by","forward_path","forward_query","utm","qr","monitor","is_notify","is_switch_unbroken_destination","tags","created_by","created_via","created_at","updated_at","expired_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"482":{"$ref":"#/components/responses/OverLimitException"},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/bulk":{"put":{"operationId":"recordBulk.update","tags":["Bulk Operations"],"parameters":[{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","required":true,"description":"Records the operation applies to. Accepted as a query object\n(`filter[host]=go.example.com`) or as a `filter` object in the JSON body.\nAt least one filter must carry a value, or every record of the workspace would match.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BulkFilterRequest"},{"type":"object","properties":{"note":{"type":"string","description":"Why the matched links exist, private to the workspace (up to 2000 characters); replaces their note, and the note they had stays in their history.","examples":["Moved to the autumn campaign, ticket MKT-88"]},"add_tags":{"type":"array","description":"Tags to add to every matched record, keeping the tags it already has (unlike `tags`, which replaces them).","examples":[["summer-2026"]],"items":{"type":"string"}},"remove_tags":{"type":"array","description":"Tags to take off every matched record; its other tags stay.","examples":[["print"]],"items":{"type":"string"}},"destination_find":{"type":"string","description":"Text to find in each record's own destinations (every A/B version), replaced by `destination_replace`. HTML pages are left alone.","examples":["mybrand.com"]},"destination_replace":{"type":"string","description":"What `destination_find` becomes; empty removes it.","examples":["yourcompany.com"]},"destination_params":{"type":"object","description":"Query parameters to add to each record's own destinations, as an object.","examples":[{"utm_campaign":"fall-2026"}],"additionalProperties":{"type":"string"}},"destination_params_overwrite":{"type":"boolean","description":"Whether `destination_params` replaces a parameter a destination already has. Defaults to true.","examples":[true]},"is_notify":{"type":"boolean","description":"Turn destination monitoring on or off for every matched record. Turning it on needs a plan with monitoring (Pro); turning it off also turns off `is_switch_unbroken_destination`.","examples":[true]},"is_switch_unbroken_destination":{"type":"boolean","description":"Send visitors to a working destination when one breaks; it takes effect on records with two or more destinations. Needs monitoring.","examples":[false]}}}]}}}},"responses":{"200":{"description":"Number of records the filter matched and the update was applied to. `still_paused` counts the matched records that a `status: active` update could not resume because the plan paused them and the workspace is still over its allowance; they resume on their own once the plan covers them. It is 0 for any other update.","content":{"application/json":{"schema":{"type":"object","examples":[{"affected":37,"still_paused":0}],"properties":{"affected":{"type":"integer"},"still_paused":{"type":"integer"}},"required":["affected","still_paused"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"delete":{"operationId":"recordBulk.destroy","tags":["Bulk Operations"],"parameters":[{"name":"note","in":"query","schema":{"type":["string","null"],"maxLength":2000}},{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","required":true,"description":"Records the operation applies to. Accepted as a query object\n(`filter[host]=go.example.com`) or as a `filter` object in the JSON body.\nAt least one filter must carry a value, or every record of the workspace would match.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"responses":{"200":{"description":"Records deleted (`affected`), and of those, how many are still being deleted in the background (`pending`). Up to a few seconds of deleting runs in the request, so most deletes come back with `pending` 0 and are already gone from listings and counts; a larger one returns as soon as that time is up and the rest leaves the listing within moments. Tags, history, monitors and the edge configuration are updated in the background either way.","content":{"application/json":{"schema":{"type":"object","examples":[{"affected":37,"pending":0}],"properties":{"affected":{"type":"integer"},"pending":{"type":"integer","minimum":0}},"required":["affected","pending"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/bulk/summary":{"post":{"operationId":"recordBulk.summary","tags":["Bulk Operations"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"},{"name":"sort","in":"query","description":"Sort results by field. Prefix with - for descending order. Available sorts: id, created_at, updated_at, total_clicks","schema":{"type":"string","enum":["id","-id","created_at","-created_at","updated_at","-updated_at","total_clicks","-total_clicks"]}},{"name":"filter","in":"query","required":true,"description":"Records the operation applies to. Accepted as a query object\n(`filter[host]=go.example.com`) or as a `filter` object in the JSON body.\nAt least one filter must carry a value, or every record of the workspace would match.\n\nAvailable filters: id, host, file, path, tld, handler, type, destination, search, tags, traffic, dns_correct, status, created_after, created_before","style":"deepObject","schema":{"type":"object","properties":{"id":{"type":"string"},"host":{"type":"string"},"file":{"type":"string"},"path":{"type":"string"},"tld":{"type":"string"},"handler":{"type":"string"},"type":{"type":"string"},"destination":{"type":"string"},"search":{"type":"string"},"tags":{"type":"string"},"traffic":{"type":"string"},"dns_correct":{"type":"string"},"status":{"type":"string"},"created_after":{"type":"string"},"created_before":{"type":"string"}}},"explode":true,"examples":{"host":{"value":{"host":"go.example.com"},"summary":"Records of a single hostname"},"tags":{"value":{"tags":"launch,paid"},"summary":"Records carrying any of the comma separated tags"}}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BulkFilterRequest"},{"type":"object","properties":{"destination_find":{"type":"string","description":"As in `PUT bulk`; previews the change.","examples":["mybrand.com"]},"destination_replace":{"type":"string","description":"As in `PUT bulk`.","examples":["yourcompany.com"]},"destination_params":{"type":"object","description":"As in `PUT bulk`; previews the change.","examples":[{"utm_campaign":"fall-2026"}],"additionalProperties":{"type":"string"}},"destination_params_overwrite":{"type":"boolean","description":"As in `PUT bulk`.","examples":[true]}}}]}}}},"responses":{"200":{"description":"What a bulk action on the filter would touch, for its confirmation: how many records, how many of each kind (`link`, `qr`, `redirect`, `migration`), how many are paused, how many had clicks in the last four weeks (this week included) and how many visits that was. Works for a whole filter as well as `filter[id]`. Sent with the Destination dialog's `destination_find` / `destination_replace` or `destination_params`, it also previews that change: how many records it `changed`, and the first five with their `from` and `to` destination (`to` is null when the record stays the same).","content":{"application/json":{"schema":{"type":"object","examples":[{"total":3,"by_kind":{"link":0,"qr":3,"redirect":0,"migration":0},"paused":0,"recent_traffic":{"links":2,"visits":312,"weeks":4,"since":"2026-09-07"}}],"properties":{"total":{"type":"integer","minimum":0},"by_kind":{"type":"object","properties":{"link":{"type":"integer","minimum":0},"qr":{"type":"integer","minimum":0},"redirect":{"type":"integer","minimum":0},"migration":{"type":"integer","minimum":0}},"required":["link","qr","redirect","migration"]},"paused":{"type":"integer","minimum":0},"recent_traffic":{"type":"object","properties":{"links":{"type":"integer","minimum":0},"visits":{"type":"integer","minimum":0},"weeks":{"type":"integer"},"since":{"type":"string"}},"required":["links","visits","weeks","since"]},"changed":{"type":"integer","minimum":0},"sample":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"from":{"type":["string","null"]},"to":{"type":["string","null"]}},"required":["id","url","from","to"]}}},"required":["total","by_kind","paused","recent_traffic"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/host/{host}/refresh":{"post":{"operationId":"host.refresh","tags":["Hostnames"],"parameters":[{"name":"host","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"responses":{"200":{"description":"The hostname after a re-check of its DNS, or of its check path for an integration. Checks are rate limited, so the state may still be the previous one.","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"domain":{"type":["string","null"]},"correct":{"type":"boolean"},"connection_mode":{"type":"string","description":"How the hostname reaches RedirHub: `managed` (DNS points to us) or `integration` (your own platform redirects; its check path proves the hostname)."},"status":{"type":"string","description":"`connected`, `dns_pending` (DNS-connected hosts), or for integrations `waiting` (its check\npath has not proven the hostname yet), `connected` or `sync_stopped` (its rules are more\nthan an hour behind, or its check path stopped answering).","enum":["sync_stopped","connected","waiting","dns_pending"]},"integration":{"description":"The integration's rules file and check path; null for DNS-connected hosts.","anyOf":[{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."},"setup":{"type":"array","description":"Only on a response with one hostname, never in a list: how to set the integration up on\neach platform offered, the same text the MCP `get-host` tool gives. `prompt` is what to\npaste into an AI coding assistant (for `caddy`, offered where its module is configured,\nthe install command and Caddyfile), null until the workspace has an integration key. It\nnever holds the key: `key_placeholder` is the text standing for it, which a client\nholding the key replaces with `` `<key>` (setting `<key_env>`) ``. `readme_url` is the\nCaddy module's guide.","items":{"type":"object","properties":{"platform":{"type":"string"},"label":{"type":"string"},"prompt":{"type":["string","null"]},"key_env":{"type":"string"},"key_placeholder":{"type":["string","null"]},"readme_url":{"type":["string","null"]}},"required":["platform","label","prompt","key_env","key_placeholder","readme_url"]}}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform","setup"]},{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform"]},{"type":"null"}]},"default_require":{"type":"string","enum":["ip","cname"]},"require":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"cname"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"string"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"ip"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"verfication"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"anyOf":[{"type":"string","const":"ssl"},{}]},"status":{"anyOf":[{"$ref":"#/components/schemas/SslStatus"},{"type":"null"}]}},"required":["scope","status"],"additionalProperties":{}},{"type":"object","properties":{"scope":{"type":"string","const":"caa"},"name":{"type":"string"},"type":{"type":"string"},"value":{"type":"string","const":"0 issue \"letsencrypt.org\""},"additional_verification":{"type":"boolean"},"exists":{"type":"boolean"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]}]}},"current":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"line":{}},"required":["type","value","line"]},{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"line":{"type":"string"}},"required":["type","name","value","line"]}]}},"errors":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","const":"ssl"},"code":{"type":["string","null"]},"message":{},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["scope","code","message","updated_at"]}},"counts":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"product":{"type":"string","const":"redirect"},"count":{"type":"integer","minimum":0}},"required":["product","count"]},{"type":"object","properties":{"product":{"type":"string","const":"short-url"},"count":{"type":"integer","minimum":0}},"required":["product","count"]}]}},"https_requested":{"type":"boolean"},"force_https":{"type":"boolean"},"ssl_renews_at":{"type":["string","null"],"format":"date-time"},"ssl_issued_at":{"type":["string","null"],"format":"date-time","description":"When the certificate now serving the host was issued."},"connected_via":{"description":"How its DNS got connected; null for an integration, which keeps its DNS.","type":["null","string","array"]},"connected_at":{"type":["string","null"],"format":"date-time","description":"When the host first pointed to RedirHub."},"dns_verified_at":{"type":["string","null"],"format":"date-time","description":"When the last check found its DNS pointing to RedirHub again."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"short_links_enabled":{"type":"boolean"},"public":{"type":"boolean"},"notice":{"type":"string"},"checked_at":{},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["host","domain","correct","connection_mode","status","integration","default_require","require","current","errors","counts","https_requested","force_https","ssl_renews_at","ssl_issued_at","connected_via","connected_at","dns_verified_at","created_by","short_links_enabled","public","notice","checked_at","created_at","updated_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/host/{host}":{"delete":{"operationId":"host.destroy","tags":["Hostnames"],"parameters":[{"name":"host","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No content","headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"put":{"operationId":"host.update","tags":["Hostnames"],"parameters":[{"name":"host","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHostRequest"}}}},"responses":{"200":{"description":"The updated hostname.","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"domain":{"type":["string","null"]},"correct":{"type":"boolean"},"connection_mode":{"type":"string","description":"How the hostname reaches RedirHub: `managed` (DNS points to us) or `integration` (your own platform redirects; its check path proves the hostname)."},"status":{"type":"string","description":"`connected`, `dns_pending` (DNS-connected hosts), or for integrations `waiting` (its check\npath has not proven the hostname yet), `connected` or `sync_stopped` (its rules are more\nthan an hour behind, or its check path stopped answering).","enum":["sync_stopped","connected","waiting","dns_pending"]},"integration":{"description":"The integration's rules file and check path; null for DNS-connected hosts.","anyOf":[{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."},"setup":{"type":"array","description":"Only on a response with one hostname, never in a list: how to set the integration up on\neach platform offered, the same text the MCP `get-host` tool gives. `prompt` is what to\npaste into an AI coding assistant (for `caddy`, offered where its module is configured,\nthe install command and Caddyfile), null until the workspace has an integration key. It\nnever holds the key: `key_placeholder` is the text standing for it, which a client\nholding the key replaces with `` `<key>` (setting `<key_env>`) ``. `readme_url` is the\nCaddy module's guide.","items":{"type":"object","properties":{"platform":{"type":"string"},"label":{"type":"string"},"prompt":{"type":["string","null"]},"key_env":{"type":"string"},"key_placeholder":{"type":["string","null"]},"readme_url":{"type":["string","null"]}},"required":["platform","label","prompt","key_env","key_placeholder","readme_url"]}}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform","setup"]},{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform"]},{"type":"null"}]},"default_require":{"type":"string","enum":["ip","cname"]},"require":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"cname"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"string"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"ip"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"verfication"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"anyOf":[{"type":"string","const":"ssl"},{}]},"status":{"anyOf":[{"$ref":"#/components/schemas/SslStatus"},{"type":"null"}]}},"required":["scope","status"],"additionalProperties":{}},{"type":"object","properties":{"scope":{"type":"string","const":"caa"},"name":{"type":"string"},"type":{"type":"string"},"value":{"type":"string","const":"0 issue \"letsencrypt.org\""},"additional_verification":{"type":"boolean"},"exists":{"type":"boolean"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]}]}},"current":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"line":{}},"required":["type","value","line"]},{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"line":{"type":"string"}},"required":["type","name","value","line"]}]}},"errors":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","const":"ssl"},"code":{"type":["string","null"]},"message":{},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["scope","code","message","updated_at"]}},"counts":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"product":{"type":"string","const":"redirect"},"count":{"type":"integer","minimum":0}},"required":["product","count"]},{"type":"object","properties":{"product":{"type":"string","const":"short-url"},"count":{"type":"integer","minimum":0}},"required":["product","count"]}]}},"https_requested":{"type":"boolean"},"force_https":{"type":"boolean"},"ssl_renews_at":{"type":["string","null"],"format":"date-time"},"ssl_issued_at":{"type":["string","null"],"format":"date-time","description":"When the certificate now serving the host was issued."},"connected_via":{"description":"How its DNS got connected; null for an integration, which keeps its DNS.","type":["null","string","array"]},"connected_at":{"type":["string","null"],"format":"date-time","description":"When the host first pointed to RedirHub."},"dns_verified_at":{"type":["string","null"],"format":"date-time","description":"When the last check found its DNS pointing to RedirHub again."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"short_links_enabled":{"type":"boolean"},"public":{"type":"boolean"},"notice":{"type":"string"},"checked_at":{},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["host","domain","correct","connection_mode","status","integration","default_require","require","current","errors","counts","https_requested","force_https","ssl_renews_at","ssl_issued_at","connected_via","connected_at","dns_verified_at","created_by","short_links_enabled","public","notice","checked_at","created_at","updated_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]},"get":{"operationId":"host.show","tags":["Hostnames"],"parameters":[{"name":"host","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested hostname with its DNS and certificate state.","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"domain":{"type":["string","null"]},"correct":{"type":"boolean"},"connection_mode":{"type":"string","description":"How the hostname reaches RedirHub: `managed` (DNS points to us) or `integration` (your own platform redirects; its check path proves the hostname)."},"status":{"type":"string","description":"`connected`, `dns_pending` (DNS-connected hosts), or for integrations `waiting` (its check\npath has not proven the hostname yet), `connected` or `sync_stopped` (its rules are more\nthan an hour behind, or its check path stopped answering).","enum":["sync_stopped","connected","waiting","dns_pending"]},"integration":{"description":"The integration's rules file and check path; null for DNS-connected hosts.","anyOf":[{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."},"setup":{"type":"array","description":"Only on a response with one hostname, never in a list: how to set the integration up on\neach platform offered, the same text the MCP `get-host` tool gives. `prompt` is what to\npaste into an AI coding assistant (for `caddy`, offered where its module is configured,\nthe install command and Caddyfile), null until the workspace has an integration key. It\nnever holds the key: `key_placeholder` is the text standing for it, which a client\nholding the key replaces with `` `<key>` (setting `<key_env>`) ``. `readme_url` is the\nCaddy module's guide.","items":{"type":"object","properties":{"platform":{"type":"string"},"label":{"type":"string"},"prompt":{"type":["string","null"]},"key_env":{"type":"string"},"key_placeholder":{"type":["string","null"]},"readme_url":{"type":["string","null"]}},"required":["platform","label","prompt","key_env","key_placeholder","readme_url"]}}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform","setup"]},{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform"]},{"type":"null"}]},"default_require":{"type":"string","enum":["ip","cname"]},"require":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"cname"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"string"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"ip"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"verfication"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"anyOf":[{"type":"string","const":"ssl"},{}]},"status":{"anyOf":[{"$ref":"#/components/schemas/SslStatus"},{"type":"null"}]}},"required":["scope","status"],"additionalProperties":{}},{"type":"object","properties":{"scope":{"type":"string","const":"caa"},"name":{"type":"string"},"type":{"type":"string"},"value":{"type":"string","const":"0 issue \"letsencrypt.org\""},"additional_verification":{"type":"boolean"},"exists":{"type":"boolean"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]}]}},"current":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"line":{}},"required":["type","value","line"]},{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"line":{"type":"string"}},"required":["type","name","value","line"]}]}},"errors":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","const":"ssl"},"code":{"type":["string","null"]},"message":{},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["scope","code","message","updated_at"]}},"counts":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"product":{"type":"string","const":"redirect"},"count":{"type":"integer","minimum":0}},"required":["product","count"]},{"type":"object","properties":{"product":{"type":"string","const":"short-url"},"count":{"type":"integer","minimum":0}},"required":["product","count"]}]}},"https_requested":{"type":"boolean"},"force_https":{"type":"boolean"},"ssl_renews_at":{"type":["string","null"],"format":"date-time"},"ssl_issued_at":{"type":["string","null"],"format":"date-time","description":"When the certificate now serving the host was issued."},"connected_via":{"description":"How its DNS got connected; null for an integration, which keeps its DNS.","type":["null","string","array"]},"connected_at":{"type":["string","null"],"format":"date-time","description":"When the host first pointed to RedirHub."},"dns_verified_at":{"type":["string","null"],"format":"date-time","description":"When the last check found its DNS pointing to RedirHub again."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"short_links_enabled":{"type":"boolean"},"public":{"type":"boolean"},"notice":{"type":"string"},"checked_at":{},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["host","domain","correct","connection_mode","status","integration","default_require","require","current","errors","counts","https_requested","force_https","ssl_renews_at","ssl_issued_at","connected_via","connected_at","dns_verified_at","created_by","short_links_enabled","public","notice","checked_at","created_at","updated_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/host":{"post":{"operationId":"host.store","tags":["Hostnames"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreHostRequest"}}}},"responses":{"200":{"description":"The hostname that is now connected to the workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string"},"domain":{"type":["string","null"]},"correct":{"type":"boolean"},"connection_mode":{"type":"string","description":"How the hostname reaches RedirHub: `managed` (DNS points to us) or `integration` (your own platform redirects; its check path proves the hostname)."},"status":{"type":"string","description":"`connected`, `dns_pending` (DNS-connected hosts), or for integrations `waiting` (its check\npath has not proven the hostname yet), `connected` or `sync_stopped` (its rules are more\nthan an hour behind, or its check path stopped answering).","enum":["sync_stopped","connected","waiting","dns_pending"]},"integration":{"description":"The integration's rules file and check path; null for DNS-connected hosts.","anyOf":[{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."},"setup":{"type":"array","description":"Only on a response with one hostname, never in a list: how to set the integration up on\neach platform offered, the same text the MCP `get-host` tool gives. `prompt` is what to\npaste into an AI coding assistant (for `caddy`, offered where its module is configured,\nthe install command and Caddyfile), null until the workspace has an integration key. It\nnever holds the key: `key_placeholder` is the text standing for it, which a client\nholding the key replaces with `` `<key>` (setting `<key_env>`) ``. `readme_url` is the\nCaddy module's guide.","items":{"type":"object","properties":{"platform":{"type":"string"},"label":{"type":"string"},"prompt":{"type":["string","null"]},"key_env":{"type":"string"},"key_placeholder":{"type":["string","null"]},"readme_url":{"type":["string","null"]}},"required":["platform","label","prompt","key_env","key_placeholder","readme_url"]}}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform","setup"]},{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform"]},{"type":"null"}]},"default_require":{"type":"string","enum":["ip","cname"]},"require":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"cname"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"string"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"ip"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"verfication"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"anyOf":[{"type":"string","const":"ssl"},{}]},"status":{"anyOf":[{"$ref":"#/components/schemas/SslStatus"},{"type":"null"}]}},"required":["scope","status"],"additionalProperties":{}},{"type":"object","properties":{"scope":{"type":"string","const":"caa"},"name":{"type":"string"},"type":{"type":"string"},"value":{"type":"string","const":"0 issue \"letsencrypt.org\""},"additional_verification":{"type":"boolean"},"exists":{"type":"boolean"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]}]}},"current":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"line":{}},"required":["type","value","line"]},{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"line":{"type":"string"}},"required":["type","name","value","line"]}]}},"errors":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","const":"ssl"},"code":{"type":["string","null"]},"message":{},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["scope","code","message","updated_at"]}},"counts":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"product":{"type":"string","const":"redirect"},"count":{"type":"integer","minimum":0}},"required":["product","count"]},{"type":"object","properties":{"product":{"type":"string","const":"short-url"},"count":{"type":"integer","minimum":0}},"required":["product","count"]}]}},"https_requested":{"type":"boolean"},"force_https":{"type":"boolean"},"ssl_renews_at":{"type":["string","null"],"format":"date-time"},"ssl_issued_at":{"type":["string","null"],"format":"date-time","description":"When the certificate now serving the host was issued."},"connected_via":{"description":"How its DNS got connected; null for an integration, which keeps its DNS.","type":["null","string","array"]},"connected_at":{"type":["string","null"],"format":"date-time","description":"When the host first pointed to RedirHub."},"dns_verified_at":{"type":["string","null"],"format":"date-time","description":"When the last check found its DNS pointing to RedirHub again."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"short_links_enabled":{"type":"boolean"},"public":{"type":"boolean"},"notice":{"type":"string"},"checked_at":{},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["host","domain","correct","connection_mode","status","integration","default_require","require","current","errors","counts","https_requested","force_https","ssl_renews_at","ssl_issued_at","connected_via","connected_at","dns_verified_at","created_by","short_links_enabled","public","notice","checked_at","created_at","updated_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]},"get":{"operationId":"host.index","tags":["Hostnames"],"responses":{"200":{"description":"A cursor-paginated page of hostnames. Follow `meta.cursor.next` for the next page.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"host":{"type":"string"},"domain":{"type":["string","null"]},"correct":{"type":"boolean"},"connection_mode":{"type":"string","description":"How the hostname reaches RedirHub: `managed` (DNS points to us) or `integration` (your own platform redirects; its check path proves the hostname)."},"status":{"type":"string","description":"`connected`, `dns_pending` (DNS-connected hosts), or for integrations `waiting` (its check\npath has not proven the hostname yet), `connected` or `sync_stopped` (its rules are more\nthan an hour behind, or its check path stopped answering).","enum":["sync_stopped","connected","waiting","dns_pending"]},"integration":{"description":"The integration's rules file and check path; null for DNS-connected hosts.","anyOf":[{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."},"setup":{"type":"array","description":"Only on a response with one hostname, never in a list: how to set the integration up on\neach platform offered, the same text the MCP `get-host` tool gives. `prompt` is what to\npaste into an AI coding assistant (for `caddy`, offered where its module is configured,\nthe install command and Caddyfile), null until the workspace has an integration key. It\nnever holds the key: `key_placeholder` is the text standing for it, which a client\nholding the key replaces with `` `<key>` (setting `<key_env>`) ``. `readme_url` is the\nCaddy module's guide.","items":{"type":"object","properties":{"platform":{"type":"string"},"label":{"type":"string"},"prompt":{"type":["string","null"]},"key_env":{"type":"string"},"key_placeholder":{"type":["string","null"]},"readme_url":{"type":["string","null"]}},"required":["platform","label","prompt","key_env","key_placeholder","readme_url"]}}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform","setup"]},{"type":"object","properties":{"rules_url":{"type":["string","null"]},"rules_etag":{"type":["string","null"],"description":"The ETag of the published rules file the integration reads: the hostname's own, or the workspace file's when the integration reported that one at the last check."},"check_url":{"type":"string"},"check_token":{"type":["string","null"]},"checked_at":{"type":["string","null"]},"check_error":{"description":"What the last check of the check path found wrong (`token`, `unreachable`, `http_{status}`), or\n`rules_too_large` while the hostname has more rules than its rules file may hold: no file is\npublished for it then, and it is left out of the workspace file, whatever the check found.","anyOf":[{"type":"string"},{"type":"null"},{"type":"string","enum":["rules_too_large"]}]},"rules_in_use":{"type":["string","null"],"description":"The ETag of the rules the integration said it uses at the last check."},"hits_url":{"type":["string","null"],"description":"Where the integration reports the visits it redirected (POST, Bearer the workspace's integration key); null where reporting is not set up."},"report_404":{"type":"boolean","description":"Whether the integration also reports the 404 pages its site answered (`report404` on its `@host` line in the rules file)."},"platform":{"type":"string","description":"The platform's name in capitals (\"REDIRHUB\"): prompts name the integration's settings after it (`REDIRHUB_INTEGRATION_KEY`), so a white-label platform's carry its own."}},"required":["rules_url","rules_etag","check_url","check_token","checked_at","check_error","rules_in_use","hits_url","report_404","platform"]},{"type":"null"}]},"default_require":{"type":"string","enum":["ip","cname"]},"require":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"scope":{"type":"string","const":"cname"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"string"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"ip"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"available":{"type":"boolean"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","available","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"type":"string","const":"verfication"},"name":{"anyOf":[{"type":"string"},{"type":"string","enum":["@"]}]},"type":{"type":"string"},"value":{"type":"string"},"additional_verification":{"type":"boolean"},"exists":{"type":"string"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]},{"type":"object","properties":{"scope":{"anyOf":[{"type":"string","const":"ssl"},{}]},"status":{"anyOf":[{"$ref":"#/components/schemas/SslStatus"},{"type":"null"}]}},"required":["scope","status"],"additionalProperties":{}},{"type":"object","properties":{"scope":{"type":"string","const":"caa"},"name":{"type":"string"},"type":{"type":"string"},"value":{"type":"string","const":"0 issue \"letsencrypt.org\""},"additional_verification":{"type":"boolean"},"exists":{"type":"boolean"},"mandatory":{"type":"boolean"}},"required":["scope","name","type","value","additional_verification","exists","mandatory"]}]}},"current":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"line":{}},"required":["type","value","line"]},{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string"},"line":{"type":"string"}},"required":["type","name","value","line"]}]}},"errors":{"type":"array","items":{"type":"object","properties":{"scope":{"type":"string","const":"ssl"},"code":{"type":["string","null"]},"message":{},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["scope","code","message","updated_at"]}},"counts":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"product":{"type":"string","const":"redirect"},"count":{"type":"integer","minimum":0}},"required":["product","count"]},{"type":"object","properties":{"product":{"type":"string","const":"short-url"},"count":{"type":"integer","minimum":0}},"required":["product","count"]}]}},"https_requested":{"type":"boolean"},"force_https":{"type":"boolean"},"ssl_renews_at":{"type":["string","null"],"format":"date-time"},"ssl_issued_at":{"type":["string","null"],"format":"date-time","description":"When the certificate now serving the host was issued."},"connected_via":{"description":"How its DNS got connected; null for an integration, which keeps its DNS.","type":["null","string","array"]},"connected_at":{"type":["string","null"],"format":"date-time","description":"When the host first pointed to RedirHub."},"dns_verified_at":{"type":["string","null"],"format":"date-time","description":"When the last check found its DNS pointing to RedirHub again."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"short_links_enabled":{"type":"boolean"},"public":{"type":"boolean"},"notice":{"type":"string"},"checked_at":{},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["host","domain","correct","connection_mode","status","integration","default_require","require","current","errors","counts","https_requested","force_https","ssl_renews_at","ssl_issued_at","connected_via","connected_at","dns_verified_at","created_by","short_links_enabled","public","notice","checked_at","created_at","updated_at"]}},"meta":{"type":"object","properties":{"cursor":{"type":"object","properties":{"current":{"type":"null"},"prev":{"type":["string","null"]},"next":{"type":["string","null"]},"count":{"type":"integer"}},"required":["current","prev","next","count"]},"counts":{"type":"string"}},"required":["cursor","counts"]}},"required":["data","meta"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/workspace/current":{"get":{"operationId":"workspace.current","tags":["Workspace"],"responses":{"200":{"description":"The workspace the API token is scoped to, with the caller's role and plan usage summary.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","const":"viewer"},"headurl":{},"logo":{"type":"string"},"personal":{"type":"boolean"},"country":{"type":["string","null"]},"pm_type":{"type":["string","null"]},"pm_ending":{"type":["string","null"]},"level":{"type":"integer"},"email":{"type":["string","null"]},"billing_extra":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"meta":{"type":"array","items":{}},"summary":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"used":{"type":"integer"}},"required":["category","used"]}},"plan":{"type":["string","null"]},"owner":{"type":"object","properties":{"name":{"type":["string","null"]}},"required":["name"]},"analytics_enabled":{"type":"boolean"},"can_use_nameservers":{"type":"boolean"},"integration_key":{"type":["object","null"],"description":"The workspace's integration key, without the key itself (shown once by `POST workspace/integration-key`); null before it has one.","properties":{"prefix":{"type":"string"},"created_at":{"type":"string"},"rules_url":{"type":"string"},"rules_error":{"type":["string","null"],"enum":["rules_too_large",null]}},"required":["prefix","created_at","rules_url","rules_error"]}},"required":["id","name","role","headurl","logo","personal","country","pm_type","pm_ending","level","email","billing_extra","created_at","updated_at","meta","summary","plan","owner","analytics_enabled","can_use_nameservers","integration_key"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/workspace/subscription":{"get":{"operationId":"workspaceSubscription.productSubscriptions","tags":["Workspace"],"responses":{"200":{"description":"The active subscriptions of the workspace, one per product still on sale. A retired product the workspace already holds stays reachable through `subscriptions` and `subscription/{product}`.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"plan":{"type":"string"},"name":{"type":"string"},"fullname":{"type":"string"},"product":{"type":"string"},"level":{"type":"integer"},"interval":{"type":"string"},"price":{"type":["number","null"],"description":"What the next invoice charges after a Stripe coupon; list_price is before it."},"list_price":{"type":["number","null"]},"discount":{"type":["object","null"],"properties":{"label":{"type":["string","null"]}},"required":["label"],"additionalProperties":{}},"product_name":{"type":"string"},"order_no":{"type":["string","null"]},"status":{"type":"string","enum":["active","upcoming","expired"]},"created_at":{"type":["string","null"],"format":"date-time"},"expiry_time":{"type":["string","null"],"format":"date-time"},"is_subscription":{"type":"boolean"},"subscription_status":{"type":["string","null"]},"subscription_ends_at":{"type":["string","null"],"format":"date-time"},"trial_ends_at":{},"payment_line":{"type":"string"},"warning_line":{"type":["string","null"]},"actions":{"anyOf":[{"type":"array","prefixItems":[{"type":"string","const":"renew"}],"minItems":1,"maxItems":1},{"type":"array","prefixItems":[{"type":"string","const":"upgrade"}],"minItems":1,"maxItems":1},{"type":"array","prefixItems":[{"type":"string","const":"legacy_cancel"}],"minItems":1,"maxItems":1},{"type":"array","items":{"type":"string"},"minItems":0,"maxItems":0}]},"limits":{"type":"array","items":{"type":"object","properties":{"id":{},"label":{"type":"string"},"used":{"type":"integer","description":"used in email, not FE"},"usedDisplay":{"type":"string"},"included":{"description":"used in email, not FE","type":"number"},"includedDisplay":{"type":"string"},"percent":{"description":"used in email, not FE"},"primary":{"type":"boolean"}},"required":["id","label","used","usedDisplay","included","includedDisplay","percent","primary"]}},"features":{"type":"object","additionalProperties":{"type":"object","properties":{"id":{},"label":{"type":"string"},"tooltip":{"type":["string","null"]}},"required":["id","label","tooltip"]}},"active_addons":{"type":"array","items":{}},"scheduled_change":{"type":["object","null"],"description":"A downgrade booked for the next billing period. Null while nothing is pending;\nthe limits above keep describing the capacity that is paid for until then.","properties":{"plan":{"type":"string"},"interval":{"type":"string"},"addons":{"type":"array","items":{"type":"string"}},"effective_at":{"type":"string"},"scheduled_at":{"type":"string"}},"required":["plan","interval","addons","effective_at","scheduled_at"]},"referral":{"type":["string","null"],"description":"The refer-a-friend programme for this workspace: the invite waiting for its first\npayment, the credit on its balance and the programme's offer (null once it ends)."}},"required":["plan","name","fullname","product","level","interval","price","list_price","discount","product_name","order_no","status","created_at","expiry_time","is_subscription","subscription_status","subscription_ends_at","trial_ends_at","payment_line","warning_line","actions","limits","features","active_addons","scheduled_change","referral"]}}},"required":["data"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/workspace/subscription/{product}":{"get":{"operationId":"workspaceSubscription.subscription","tags":["Workspace"],"parameters":[{"name":"product","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The workspace subscription for the given product. A product without a subscription still answers `200`, with an empty JSON array (`[]`) rather than an empty body.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"plan":{"type":"string"},"name":{"type":"string"},"fullname":{"type":"string"},"product":{"type":"string"},"level":{"type":"integer"},"interval":{"type":"string"},"price":{"type":["number","null"],"description":"What the next invoice charges after a Stripe coupon; list_price is before it."},"list_price":{"type":["number","null"]},"discount":{"type":["object","null"],"properties":{"label":{"type":["string","null"]}},"required":["label"],"additionalProperties":{}},"product_name":{"type":"string"},"order_no":{"type":["string","null"]},"status":{"type":"string","enum":["active","upcoming","expired"]},"created_at":{"type":["string","null"],"format":"date-time"},"expiry_time":{"type":["string","null"],"format":"date-time"},"is_subscription":{"type":"boolean"},"subscription_status":{"type":["string","null"]},"subscription_ends_at":{"type":["string","null"],"format":"date-time"},"trial_ends_at":{},"payment_line":{"type":"string"},"warning_line":{"type":["string","null"]},"actions":{"anyOf":[{"type":"array","prefixItems":[{"type":"string","const":"renew"}],"minItems":1,"maxItems":1},{"type":"array","prefixItems":[{"type":"string","const":"upgrade"}],"minItems":1,"maxItems":1},{"type":"array","prefixItems":[{"type":"string","const":"legacy_cancel"}],"minItems":1,"maxItems":1},{"type":"array","items":{"type":"string"},"minItems":0,"maxItems":0}]},"limits":{"type":"array","items":{"type":"object","properties":{"id":{},"label":{"type":"string"},"used":{"type":"integer","description":"used in email, not FE"},"usedDisplay":{"type":"string"},"included":{"description":"used in email, not FE","type":"number"},"includedDisplay":{"type":"string"},"percent":{"description":"used in email, not FE"},"primary":{"type":"boolean"}},"required":["id","label","used","usedDisplay","included","includedDisplay","percent","primary"]}},"features":{"type":"object","additionalProperties":{"type":"object","properties":{"id":{},"label":{"type":"string"},"tooltip":{"type":["string","null"]}},"required":["id","label","tooltip"]}},"active_addons":{"type":"array","items":{}},"scheduled_change":{"type":["object","null"],"description":"A downgrade booked for the next billing period. Null while nothing is pending;\nthe limits above keep describing the capacity that is paid for until then.","properties":{"plan":{"type":"string"},"interval":{"type":"string"},"addons":{"type":"array","items":{"type":"string"}},"effective_at":{"type":"string"},"scheduled_at":{"type":"string"}},"required":["plan","interval","addons","effective_at","scheduled_at"]},"referral":{"type":["string","null"],"description":"The refer-a-friend programme for this workspace: the invite waiting for its first\npayment, the credit on its balance and the programme's offer (null once it ends)."}},"required":["plan","name","fullname","product","level","interval","price","list_price","discount","product_name","order_no","status","created_at","expiry_time","is_subscription","subscription_status","subscription_ends_at","trial_ends_at","payment_line","warning_line","actions","limits","features","active_addons","scheduled_change","referral"]},{"type":"array","items":{"type":"string"},"minItems":0,"maxItems":0}]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/workspace/update/{metaKey}":{"post":{"operationId":"workspace.update","tags":["Workspace"],"parameters":[{"name":"metaKey","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string","maxLength":256}},"required":["value"]}}}},"responses":{"200":{"description":"The updated workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","const":"viewer"},"headurl":{},"logo":{"type":"string"},"personal":{"type":"boolean"},"country":{"type":["string","null"]},"pm_type":{"type":["string","null"]},"pm_ending":{"type":["string","null"]},"level":{"type":"integer"},"email":{"type":["string","null"]},"billing_extra":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"meta":{"type":"array","items":{}},"summary":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"used":{"type":"integer"}},"required":["category","used"]}},"plan":{"type":["string","null"]},"owner":{"type":"object","properties":{"name":{"type":["string","null"]}},"required":["name"]},"analytics_enabled":{"type":"boolean"},"can_use_nameservers":{"type":"boolean"},"integration_key":{"type":["object","null"],"description":"The workspace's integration key, without the key itself (shown once by `POST workspace/integration-key`); null before it has one.","properties":{"prefix":{"type":"string"},"created_at":{"type":"string"},"rules_url":{"type":"string"},"rules_error":{"type":["string","null"],"enum":["rules_too_large",null]}},"required":["prefix","created_at","rules_url","rules_error"]}},"required":["id","name","role","headurl","logo","personal","country","pm_type","pm_ending","level","email","billing_extra","created_at","updated_at","meta","summary","plan","owner","analytics_enabled","can_use_nameservers","integration_key"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"400":{"$ref":"#/components/responses/AppException"},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/workspace/integration-key":{"post":{"operationId":"workspace.integrationKey","summary":"The workspace's integration key, created when it has none. Integrations send it as\n`Authorization: Bearer <key>` when they report visits to the host's `integration.hits_url`;\nthe same key serves every integration of the workspace. With `rotate` it is replaced: the\nold key stops at once and every rules file moves to a new address, so each integration\nneeds the new key and its new rules URL. No other response carries the key. Managers and\nowners only","tags":["Workspace"],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Any unique value, e.g. a UUID, to make a retry safe: the same key sent again within 24 hours returns the first response, with `Idempotent-Replayed: true`, instead of creating another record. Only a successful response is kept, so a failed request can be sent again with the same key. Reusing a key for a different request returns 422; a retry while the first request is still running returns 409.","schema":{"type":"string","maxLength":255},"example":"5f0c7d2e-8a4b-4f1e-9c3a-2b7d6e1f0a94"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationKeyRequest"}}}},"responses":{"200":{"description":"The integration key; the workspace itself shows only its prefix and creation time (`integration_key`).","content":{"application/json":{"schema":{"type":"object","examples":[{"key":"reh_int_8Kd2Xa91LmQpZ0rT5vWyB3cN","prefix":"reh_int_8Kd2","created_at":"2026-11-05T09:30:00+00:00"}],"properties":{"key":{"type":"string"},"prefix":{"type":"string"},"created_at":{"type":"string"}},"required":["key","prefix","created_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Present, with `true`, when the response is the stored response of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string"},"example":"true"}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"409":{"description":"A request with the same `Idempotency-Key` is still running","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["A request with this Idempotency-Key is still running. Retry it in a moment."]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}},"484":{"$ref":"#/components/responses/RoleException"}},"security":[{"http":[]}]}},"/workspace/{id}":{"get":{"operationId":"workspace.show","tags":["Workspace"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The requested workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","const":"viewer"},"headurl":{},"logo":{"type":"string"},"personal":{"type":"boolean"},"country":{"type":["string","null"]},"pm_type":{"type":["string","null"]},"pm_ending":{"type":["string","null"]},"level":{"type":"integer"},"email":{"type":["string","null"]},"billing_extra":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"meta":{"type":"array","items":{}},"summary":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"used":{"type":"integer"}},"required":["category","used"]}},"plan":{"type":["string","null"]},"owner":{"type":"object","properties":{"name":{"type":["string","null"]}},"required":["name"]},"analytics_enabled":{"type":"boolean"},"can_use_nameservers":{"type":"boolean"},"integration_key":{"type":["object","null"],"description":"The workspace's integration key, without the key itself (shown once by `POST workspace/integration-key`); null before it has one.","properties":{"prefix":{"type":"string"},"created_at":{"type":"string"},"rules_url":{"type":"string"},"rules_error":{"type":["string","null"],"enum":["rules_too_large",null]}},"required":["prefix","created_at","rules_url","rules_error"]}},"required":["id","name","role","headurl","logo","personal","country","pm_type","pm_ending","level","email","billing_extra","created_at","updated_at","meta","summary","plan","owner","analytics_enabled","can_use_nameservers","integration_key"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/test":{"get":{"operationId":"account.test","tags":["Account & Reference"],"responses":{"200":{"description":"The token is valid and identifies the authenticated account.","content":{"application/json":{"schema":{"type":"object","examples":[{"email":"jane@example.com","message":"This API Token is valid and active"}],"properties":{"email":{"type":"string"},"message":{"type":"string","const":"This API Token is valid and active"}},"required":["email","message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/account":{"get":{"operationId":"account.index","tags":["Account & Reference"],"responses":{"200":{"description":"The authenticated account.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"email_verified":{"type":"boolean"},"name":{"type":"string"},"headurl":{},"current_workspace":{},"login_workspace":{"type":["string","null","array"]},"phone":{"type":["string","null"]},"phone_verified":{"type":"boolean"},"im":{"type":["string","null"]},"last_login_ip":{"type":["string","null"]},"two_factor_enabled":{"type":"boolean"},"password_last_changed":{"type":["string","null","array"]},"language":{"type":"string"},"timezone":{"type":["string","null"]},"country":{"type":["string","null"]},"connected":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"openid":{"type":["string","null","array"]},"manage":{"type":"null"}},"required":["provider","openid","manage"]}},"meta":{"type":"array","items":{}},"onboarding_completed":{"type":"boolean","description":"The dashboard's one onboarding step after sign-up has been answered."},"plan_intent":{"type":["string","null"],"description":"The plan the sign-up started from on the pricing page: Go live offers it first."},"create_intent":{"type":["string","null"],"description":"What the user picked first in the create chooser (redirect, branded, qr, migration, import)."},"created_at":{"type":["string","null"],"format":"date-time"}},"required":["id","email","email_verified","name","headurl","current_workspace","login_workspace","phone","phone_verified","im","last_login_ip","two_factor_enabled","password_last_changed","language","timezone","country","connected","meta","onboarding_completed","plan_intent","create_intent","created_at"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/shared/plugins":{"get":{"operationId":"record.plugins","tags":["Account & Reference"],"responses":{"200":{"description":"Plugins that can be enabled on a record. `as_paid_feature` names the plan feature a paid plugin requires, and is `null` when the plugin is free.","content":{"application/json":{"schema":{"type":"array","examples":[[{"id":"nowechat","label":"Block WeChat","description":"Block WeChat in-app browsers.","as_paid_feature":null},{"id":"nobot","label":"Block bots","description":"Block known crawlers and bots.","as_paid_feature":null},{"id":"protection","label":"Protection","description":"Protect the destination behind a check.","as_paid_feature":null}]],"items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"description":{"type":["string","null"]},"as_paid_feature":{"type":["string","null"]}},"required":["id","label","description","as_paid_feature"]}}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}},"/shared/types":{"get":{"operationId":"record.types","tags":["Account & Reference"],"responses":{"200":{"description":"Record types (`data`) and multi-destination routing strategies (`distributes`). `as_paid_feature` names the plan feature a paid option requires.","content":{"application/json":{"schema":{"type":"object","examples":[{"data":[{"id":"301","label":"301","short":"301","description":"Permanent redirect.","as_paid_feature":null},{"id":"txt","label":"TXT","short":"TXT","description":"Serve plain text.","as_paid_feature":"record.txt"}],"distributes":[{"id":"random","label":"Random","description":"Pick a destination at random.","as_paid_feature":null},{"id":"fastest","label":"Fastest","description":"Pick the fastest destination.","as_paid_feature":"record.fastest"}]}],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"short":{"type":"string"},"description":{"type":["string","null"]},"as_paid_feature":{"type":["string","null"]}},"required":["id","label","short","description","as_paid_feature"]}},"distributes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"description":{"type":["string","null"]},"as_paid_feature":{"type":["string","null"]}},"required":["id","label","description","as_paid_feature"]}}},"required":["data","distributes"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"429":{"description":"Too many requests","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview.","examples":["Too Many Attempts."]}},"required":["message"]}}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed within the current window.","schema":{"type":"integer"},"example":500},"X-RateLimit-Remaining":{"description":"Requests still available within the current window.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":60},"X-RateLimit-Reset":{"description":"Unix timestamp at which the current window resets.","schema":{"type":"integer"}}}}},"security":[{"http":[]}]}}},"components":{"securitySchemes":{"http":{"type":"http","scheme":"bearer","bearerFormat":"sanctum"}},"schemas":{"BulkFilterRequest":{"type":"object","description":"Scope guard of the destructive bulk endpoints.\n\nThe bulk update, delete and export operations run on whatever\n{@see \\Modules\\Record\\Actions\\FilterRecordsAction} matches, which without a filter is every\nrecord of the workspace. Requiring the filter turns \"delete everything\" into an explicit\nchoice instead of the result of a forgotten query parameter.","properties":{"note":{"type":["string","null"],"maxLength":2000}},"title":"BulkFilterRequest"},"ConnectionMode":{"type":"string","description":"How a hostname reaches RedirHub. `managed`: its DNS points to us and the edge serves it once its DNS check passes (NS, CNAME or TXT). `integration`: its DNS stays where it is; the customer's own CDN, app or CMS downloads the rules and redirects, and the first answer of its check path with the workspace's check token proves the workspace owns it (IntegrationHealth::checkMany(), HostOwnership::activateIntegration()). Both are probed by the same hostname check (system:dns-check, BulkVerifyDns), on the same schedule. The edge never serves an integration's links (EdgeRecordQuery). Both proofs end in `active` and `dns_correct`, so the mode never decides who a hostname belongs to. An integration has no grace period; one switched back to `managed` gets the grace period of a newly added hostname where no other workspace holds it (HostOwnership::switchConnectionMode()).\n","enum":["managed","integration"],"title":"ConnectionMode"},"CreateLinkRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":250},"type":{"type":"string"},"description":{"type":"string","maxLength":300},"note":{"type":["string","null"],"maxLength":2000},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":"array","items":{"type":"string"}},"destination":{"type":["string","null"]},"destinations":{"type":["array","null"],"items":{"type":"string"}},"plugins":{"type":["array","null"],"items":{"type":"string"}},"is_notify":{"type":"boolean"},"is_switch_unbroken_destination":{"type":"boolean"},"expires":{"type":"string"},"password":{"type":["string","null"],"description":"Visitors enter it before the edge redirects them; null removes it. Write-only.","minLength":4,"maxLength":128},"qr":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"]},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string","enum":["s","m","l"]}},"required":["theme","color","logo","show_url","margin"]},"host":{"type":"string","maxLength":100},"alias":{"type":"string","maxLength":30},"destination_routing":{"type":"string"},"status":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}}},"required":["host"],"title":"CreateLinkRequest"},"DestinationRouting":{"type":"string","enum":["random","order","first","fastest"],"title":"DestinationRouting"},"FilterPinsRequest":{"type":"object","properties":{"pins":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["host","tag","qr","type","health","created"]},"value":{"type":"string","maxLength":255}},"required":["kind","value"]},"maxItems":10}},"required":["pins"],"title":"FilterPinsRequest"},"IntegrationKeyRequest":{"type":"object","description":"Show the workspace's integration key, or replace it with `rotate`.","properties":{"rotate":{"type":"boolean","description":"Replace the key: the old one stops working at once and every rules URL of the workspace changes."}},"title":"IntegrationKeyRequest"},"RecordHandler":{"type":"string","description":"What the link is: `short-url` for a short link and `qr` for a dynamic QR code, both served on a short link domain; `redirect` for a domain redirect and `migration` for a website migration mapping, both served on the redirected domain.\n","enum":["short-url","qr","redirect","migration"],"title":"RecordHandler"},"RedirectRequest":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string","maxLength":250},"type":{"type":"string"},"description":{"type":"string","maxLength":300},"note":{"type":["string","null"],"maxLength":2000},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":"array","items":{"type":"string"}},"destination":{"type":["string","null"]},"destinations":{"type":["array","null"],"items":{"type":"string"}},"plugins":{"type":["array","null"],"items":{"type":"string"}},"is_notify":{"type":"boolean"},"is_switch_unbroken_destination":{"type":"boolean"},"expires":{"type":"string"},"password":{"type":["string","null"],"minLength":4,"maxLength":128}},"required":["url"],"title":"RedirectRequest"},"SslStatus":{"type":"string","enum":["pending","processing","issued","dns_pending","error"],"title":"SslStatus"},"StoreHostRequest":{"type":"object","properties":{"host":{"type":"string","description":"The hostname to connect, e.g. `go.example.com`. Wildcards are not accepted here."},"https_requested":{"type":"boolean","description":"Whether the platform should issue and renew an SSL certificate for this hostname\nand accept HTTPS traffic on it. Defaults to `true` for a hostname that is being\nconnected for the first time, and leaves an already connected one untouched."},"short_links_enabled":{"type":"boolean","description":"Whether this hostname may be used to create new short links. QR codes are generated from short links, so this also controls QR code creation on this hostname. Existing links and QR codes continue to resolve when disabled."},"connection_mode":{"description":"How the hostname reaches RedirHub: `managed` (its DNS points to us, the default) or\n`integration` (your own CDN, app or CMS downloads the rules). An integration is verified\nthe first time its check path (`integration.check_url`) answers with its check token, and\nkeeps HTTPS on your own platform.","$ref":"#/components/schemas/ConnectionMode"}},"required":["host"],"title":"StoreHostRequest"},"StoreLinksRequest":{"type":"object","description":"Create a record of any handler through `POST /links`.\n\nShort links (`short-url`, `qr`) take a `host` and an optional `alias`, and may carry a QR\ncode style; redirects (`redirect`, `migration`) take the `url` they answer for, and are held\nto the same plan features as `POST /redirect`.\n\nA workspace without a paid plan may save a link before choosing one (`pending_plan`): it\nis saved paused, without the options of Record::PENDING_PLAN_OPTIONS, which wait on the record\nuntil a paid plan includes them and then turn it on. The options of Record::PENDING_PLAN_FEATURES\n(A/B destinations, fastest routing, an HTML page, a wildcard source) are saved on it as they are,\nmarked, and keep it paused until a plan includes them. Tags are still refused.","properties":{"title":{"type":"string","maxLength":250},"type":{"type":"string"},"description":{"type":"string","maxLength":300},"note":{"type":["string","null"],"maxLength":2000},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":"array","items":{"type":"string"}},"destination":{"type":["string","null"]},"destinations":{"type":["array","null"],"items":{"type":"string"}},"plugins":{"type":["array","null"],"items":{"type":"string"}},"is_notify":{"type":"boolean"},"is_switch_unbroken_destination":{"type":"boolean"},"expires":{"type":"string"},"password":{"type":["string","null"],"description":"Visitors enter it before the edge redirects them; null removes it. Write-only.","minLength":4,"maxLength":128},"handler":{"$ref":"#/components/schemas/RecordHandler"},"destination_routing":{"type":"string"},"status":{"type":"integer","enum":["1","0"]},"tags":{"type":"array","items":{"type":"string"}},"qr":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"]},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string","enum":["s","m","l"]}},"required":["theme","color","logo","show_url","margin"]},"pending_plan":{"type":"boolean"},"host":{"type":"string","maxLength":100},"alias":{"type":"string","maxLength":30},"url":{"type":"string"}},"required":["handler","host"],"title":"StoreLinksRequest"},"Tag":{"type":"object","properties":{"id":{"type":"integer"},"org_id":{"type":["integer","null"]},"slug":{"type":"string"},"name":{"type":"string"},"suggest":{"type":"boolean"},"count":{"type":"integer"},"tag_group_id":{"type":["integer","null"]},"description":{"type":["string","null"]}},"required":["id","org_id","slug","name","suggest","count","tag_group_id","description"],"title":"Tag"},"UpdateHostRequest":{"type":"object","properties":{"https_requested":{"type":"boolean","description":"Whether the platform should issue and renew an SSL certificate for this hostname\nand accept HTTPS traffic on it."},"force_https":{"type":"boolean","description":"Whether visitors opening this hostname over HTTP are sent to HTTPS once its certificate is issued.\nTurning it on needs an Enterprise plan; turning it off is always allowed."},"short_links_enabled":{"type":"boolean","description":"Whether this hostname may be used to create new short links. QR codes are generated from short links, so this also controls QR code creation on this hostname. Existing links and QR codes continue to resolve when disabled."},"connection_mode":{"description":"How the hostname reaches RedirHub: `managed` (its DNS points to us) or `integration` (your\nown CDN, app or CMS downloads the rules and answers the check path, which proves the\nhostname is yours). Switching to `integration` turns HTTPS off: the certificate stays\nwith your own platform. It takes effect at once: RedirHub's edge stops serving the\nhostname's links right away, so while its DNS still points to us they stop working\nuntil your platform serves the rules and answers the check path. Set the platform up\nfirst. A wildcard hostname cannot be an integration.","$ref":"#/components/schemas/ConnectionMode"},"report_404":{"type":"boolean","description":"For an integration: whether it also reports the 404 pages your site answered, so you\nsee the URLs it cannot find. On by default; the integration picks a change up with\nits next rules download (`report404` on its `@host` line in the rules file)."}},"title":"UpdateHostRequest"},"UpdateLinkRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":250},"type":{"type":"string"},"description":{"type":"string","maxLength":300},"note":{"type":["string","null"],"maxLength":2000},"forward_path":{"type":["boolean","null"]},"forward_query":{"type":["boolean","null"]},"utm":{"type":"array","items":{"type":"string"}},"destination":{"type":["string","null"]},"destinations":{"type":["array","null"],"items":{"type":"string"}},"plugins":{"type":["array","null"],"items":{"type":"string"}},"is_notify":{"type":"boolean"},"is_switch_unbroken_destination":{"type":"boolean"},"expires":{"type":"string"},"password":{"type":["string","null"],"description":"Visitors enter it before the edge redirects them; null removes it. Write-only.","minLength":4,"maxLength":128},"qr":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"]},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string","enum":["s","m","l"]}},"required":["theme","color","logo","show_url","margin"]},"alias":{"type":"string"},"host":{"type":"string"},"url":{"type":"string"},"path":{"type":"string"},"file":{"type":"string"},"tld":{"type":"string"},"destination_routing":{"type":"string"},"status":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}}},"title":"UpdateLinkRequest"},"UpdateLinksRequest":{"type":"object","description":"Update a record of any handler through `PUT /links/{id}`.\n\nThe record keeps its handler and source URL. Short links (`short-url`, `qr`) take the same\nfields as `PUT /link/{id}`, QR code style included; redirects (`redirect`, `migration`) take\nthe same fields as `PUT /redirect/{id}` and are held to the same plan features.","properties":{"qr":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"]},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"logo":{"type":"boolean"},"show_url":{"type":"boolean"},"margin":{"type":"string","enum":["s","m","l"]}},"required":["theme","color","logo","show_url","margin"]}},"title":"UpdateLinksRequest"}},"responses":{"AuthenticationException":{"description":"Unauthenticated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview."}},"required":["message"]}}}},"RoleException":{"description":"The workspace role of the authenticated user is too low for this action.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview."},"desiredRole":{"type":"string","description":"The role the action requires."}},"required":["message","desiredRole"]}}}},"AppException":{"description":"The request could not be completed.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview."}},"required":["message"]}}}},"ValidationException":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Errors overview."},"errors":{"type":"object","description":"A detailed description of each field that failed validation.","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["message","errors"]}}}},"OverLimitException":{"description":"The action would exceed a plan limit of the current workspace.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Error overview."},"cat":{"type":"string","description":"The product the limit belongs to."},"unit":{"type":"string","description":"The limited unit, such as `records` or `visits`."}},"required":["message","cat","unit"]}}}}}}}