{"openapi":"3.1.0","info":{"title":"Inkpage Links API","description":"Link shortener with custom subdomains and analytics, 100% on Cloudflare.\n\n[Back to Inkpage Links](/) · [Source code](https://github.com/alexlivre/InkPage-Sink)"},"servers":[{"url":"https://inkpage.link","description":"Local Development Server","variables":{}}],"paths":{"":{"get":{"tags":["App Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/api-keys":{"get":{"tags":["API Routes"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"maximum":100},"description":"Maximum number of keys to return"}],"responses":{"200":{"description":"OK"}},"description":"List API keys. Tokens are never returned, only their identifying prefix.","security":[{"bearerAuth":[]}]}},"/api/api-keys/create":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Create a scoped API key. The token is returned once and cannot be recovered.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}}}}},"/api/api-keys/revoke":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Revoke an API key. The token stops working after the cache entry expires.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"Identifier returned when the key was created"}}}}}}}},"/api/audit":{"get":{"tags":["API Routes"],"parameters":[{"name":"action","in":"query","required":false,"schema":{"type":"string"},"description":"Exact action filter, e.g. user.role_change"},{"name":"actorEmail","in":"query","required":false,"schema":{"type":"string"},"description":"Exact acting email filter"},{"name":"targetType","in":"query","required":false,"schema":{"type":"string"},"description":"Exact target type filter, e.g. user"},{"name":"startAt","in":"query","required":false,"schema":{"type":"integer"},"description":"Only entries at or after this unix timestamp"},{"name":"endAt","in":"query","required":false,"schema":{"type":"integer"},"description":"Only entries at or before this unix timestamp"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"maximum":100},"description":"Maximum entries to return"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"}],"responses":{"200":{"description":"OK"}},"description":"List audit log entries with filters and pagination","security":[{"bearerAuth":[]}]}},"/api/auth/google":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/auth/google/callback":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/auth/logout":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/backup":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Manually trigger a backup to R2","security":[{"bearerAuth":[]}]}},"/api/domains":{"get":{"tags":["API Routes"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Case-insensitive substring of the subdomain name"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","paused"]},"description":"Exact status filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"maximum":100},"description":"Maximum subdomains to return"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"}],"responses":{"200":{"description":"OK"}},"description":"List managed subdomains with search and pagination","security":[{"bearerAuth":[]}]}},"/api/domains/create":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Register a subdomain for an existing short link, or create the short link alongside it","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainCreate"}}}}}},"/api/domains/delete":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Delete a managed subdomain","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The subdomain id to delete"}}}}}}}},"/api/domains/update":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Pause/resume a subdomain or repoint it at another link","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainUpdate"}}}}}},"/api/invites":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}},"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/invites/{id}/revoke":{"post":{"tags":["API Routes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/link/ai":{"get":{"tags":["API Routes"],"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The URL to generate a slug for"}],"responses":{"200":{"description":"OK"}},"description":"Generate a slug using AI based on the URL","security":[{"bearerAuth":[]}]}},"/api/link/check":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Check target URLs for existing short links","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"cursor":{"type":"string","description":"Pagination cursor from the previous response"},"limit":{"type":"integer","default":6,"minimum":1,"maximum":10,"description":"Maximum number of links to check"},"timeout":{"type":"integer","default":6,"minimum":1,"maximum":30,"description":"Timeout in seconds for each link"}}}}}}}},"/api/link/count":{"get":{"tags":["API Routes"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Case-insensitive substring to match against slug, URL, comment, or tag"},{"name":"url","in":"query","required":false,"schema":{"type":"string"},"description":"Normalized target URL to match exactly"},{"name":"tag","in":"query","required":false,"schema":{"type":"string"},"description":"Exact normalized tag filter"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","expired","all"],"default":"active"},"description":"Expiration status filter"}],"responses":{"200":{"description":"OK"}},"description":"Count links matching keyword, URL, tag, and expiration status filters","security":[{"bearerAuth":[]}]}},"/api/link/create":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Create a new short link","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLink"}}}}}},"/api/link/delete":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Delete a short link","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"The slug of the link to delete"}}}}}}}},"/api/link/edit":{"put":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Edit an existing short link","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditLink"}}}}}},"/api/link/export":{"get":{"tags":["API Routes"],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","expired","all"],"default":"all"},"description":"Expiration status filter"}],"responses":{"200":{"description":"OK"}},"description":"Export all links with pagination","security":[{"bearerAuth":[]}]}},"/api/link/import":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Import links from exported data","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportData"}}}}}},"/api/link/list":{"get":{"tags":["API Routes"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"maximum":1000},"description":"Maximum number of links to return"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["az","za","newest","oldest"],"default":"newest"},"description":"Link sort order"},{"name":"tag","in":"query","required":false,"schema":{"type":"string"},"description":"Exact normalized tag filter"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","expired","all"],"default":"active"},"description":"Expiration status filter"}],"responses":{"200":{"description":"OK"}},"description":"List all short links with pagination","security":[{"bearerAuth":[]}]}},"/api/link/migration/run":{"post":{"tags":["API Routes"],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque migration run cursor"},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Rescan KV without overwriting D1 rows"}],"responses":{"200":{"description":"OK"}},"description":"Migrate one bounded page of legacy KV links to D1","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"cursor":{"type":"string","description":"Opaque migration run cursor"},"force":{"type":"boolean","default":false,"description":"Rescan KV without overwriting D1 rows"}}}}}}}},"/api/link/migration/status":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Get KV to D1 link migration status","security":[{"bearerAuth":[]}]}},"/api/link/og-ai":{"get":{"tags":["API Routes"],"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","format":"uri"},"description":"The URL to generate OpenGraph metadata for"},{"name":"locale","in":"query","required":false,"schema":{"type":"string"},"description":"Preferred locale for the generated metadata"}],"responses":{"200":{"description":"OK"}},"description":"Generate OpenGraph title and description using AI based on the URL","security":[{"bearerAuth":[]}]}},"/api/link/query":{"get":{"tags":["API Routes"],"parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string"},"description":"The slug of the link to query"}],"responses":{"200":{"description":"OK"}},"description":"Query a short link by slug","security":[{"bearerAuth":[]}]}},"/api/link/search":{"get":{"tags":["API Routes"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Non-empty case-insensitive substring to match against slug, URL, comment, or tag"},{"name":"url","in":"query","required":false,"schema":{"type":"string"},"description":"Normalized target URL to match exactly"},{"name":"tag","in":"query","required":false,"schema":{"type":"string"},"description":"Exact normalized tag filter"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","expired","all"],"default":"active"},"description":"Expiration status filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000,"default":20},"description":"Maximum matches for keyword or exact URL searches"}],"responses":{"200":{"description":"OK"}},"description":"Search links with a non-empty keyword or exact URL. Tag and status only filter those searches; requests without a search selector return an empty array.","security":[{"bearerAuth":[]}]},"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Search links by an exact target URL without placing the URL in the request query string","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExactUrlSearch"}}}}}},"/api/link/tags":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"List tags currently used by links","security":[{"bearerAuth":[]}]}},"/api/link/upsert":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Create a short link, or return the existing one when the slug is taken","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLink"}}}}}},"/api/location":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"The location of the user"}},"description":"Get the location of the user"}},"/api/logs/events":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/logs/locations":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/mcp":{"get":{"tags":["MCP"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Model Context Protocol endpoint (Streamable HTTP, stateless) served by the official @modelcontextprotocol/server SDK v2. Accepts standard MCP messages such as initialize, tools/list, tools/call, and ping. A message without an `id` is a notification and is answered with 202.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","method"],"additionalProperties":true,"description":"`method` is one of initialize, notifications/initialized, tools/list, tools/call, or ping."}}}}}},"/api/settings/registration":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}},"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/stats/{action}":{"get":{"tags":["API Routes"],"parameters":[{"name":"action","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/stats/counters":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/stats/heatmap":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/stats/metrics":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/stats/views":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/api/upload/image":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Upload an image to R2 storage","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","slug"],"properties":{"file":{"type":"string","format":"binary"},"slug":{"type":"string"}}}}}}}},"/api/users":{"get":{"tags":["API Routes"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Case-insensitive substring of the email"},{"name":"role","in":"query","required":false,"schema":{"type":"string","enum":["superadmin","admin","power-user","member","viewer"]},"description":"Exact role filter"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["active","suspended"]},"description":"Exact status filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"maximum":100},"description":"Maximum accounts to return"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"}],"responses":{"200":{"description":"OK"}},"description":"List user accounts with search, filters, and pagination","security":[{"bearerAuth":[]}]}},"/api/users/role":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Grant or change a user role. The superadmin level is env-only and rejected.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","role"],"properties":{"id":{"type":"string","description":"The user id to update"},"role":{"type":"string","enum":["admin","member","viewer"],"description":"The role to grant"}}}}}}}},"/api/users/status":{"post":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"OK"}},"description":"Suspend or reactivate a user account. The change applies on the next request.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string","description":"The user id to update"},"status":{"type":"string","enum":["active","suspended"],"description":"The status to set"}}}}}}}},"/api/verify":{"get":{"tags":["API Routes"],"parameters":[],"responses":{"200":{"description":"The authentication credentials are valid"},"default":{"description":"The authentication credentials are invalid"}},"description":"Verify the current authentication method"}},"/_assets/{key}":{"get":{"tags":["Internal"],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/__nuxt_error":{"get":{"tags":["Internal"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/_i18n/{hash}/{locale}/messages.json":{"get":{"tags":["Internal"],"parameters":[{"name":"hash","in":"path","required":true,"schema":{"type":"string"}},{"name":"locale","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/__nuxt_island/{*param1}":{"get":{"tags":["Internal"],"parameters":[{"name":"*param1","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/_docs/openapi.json":{"get":{"tags":["Internal"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/_docs/scalar":{"get":{"tags":["Internal"],"parameters":[],"responses":{"200":{"description":"OK"}}}},"/_docs/swagger":{"get":{"tags":["Internal"],"parameters":[],"responses":{"200":{"description":"OK"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Instance site token (NUXT_SITE_TOKEN) or a scoped API key (ink_…)"}},"schemas":{"CreateLink":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":16384,"format":"uri","description":"The target URL."},"slug":{"type":"string","maxLength":2048,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"comment":{"description":"Optional internal note.","type":"string","maxLength":2048},"expiration":{"description":"Unix seconds. Must be in the future.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"description":"Overrides the title in the link preview.","type":"string","maxLength":256},"description":{"description":"Overrides the description in the link preview.","type":"string","maxLength":2048},"image":{"description":"Preview image: an uploaded key or an absolute http(s) URL.","type":"string"},"apple":{"description":"Apple App Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"google":{"description":"Google Play Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"cloaking":{"description":"Mask the destination URL behind the short link.","type":"boolean"},"redirectWithQuery":{"description":"Append incoming query parameters to the destination URL.","type":"boolean"},"proxy":{"description":"Reverse-proxy the destination instead of redirecting.","type":"boolean"},"password":{"type":"string","minLength":1,"maxLength":128,"description":"Password protection for the link."},"unsafe":{"description":"Show a warning page before redirecting.","type":"boolean"},"geo":{"description":"Geo-routing rules mapping a two-letter country code to a URL.","type":"object","propertyNames":{"type":"string","pattern":"^[A-Z]{2}$"},"additionalProperties":{"type":"string","maxLength":16384,"format":"uri"}},"tags":{"description":"Up to 10 normalized link tags, each 1-32 characters.","maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":32}},"id":{"type":"string","minLength":1,"maxLength":26},"createdAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updatedAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["url"]},"EditLink":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":16384,"format":"uri","description":"The target URL."},"slug":{"type":"string","maxLength":2048,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"The slug identifying the short link."},"comment":{"description":"Optional internal note.","type":"string","maxLength":2048},"expiration":{"description":"Unix seconds. Must be in the future.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"description":"Overrides the title in the link preview.","type":"string","maxLength":256},"description":{"description":"Overrides the description in the link preview.","type":"string","maxLength":2048},"image":{"description":"Preview image: an uploaded key or an absolute http(s) URL.","type":"string"},"apple":{"description":"Apple App Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"google":{"description":"Google Play Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"cloaking":{"description":"Mask the destination URL behind the short link.","type":"boolean"},"redirectWithQuery":{"description":"Append incoming query parameters to the destination URL.","type":"boolean"},"proxy":{"description":"Reverse-proxy the destination instead of redirecting.","type":"boolean"},"password":{"description":"Password protection for the link. An empty string clears it; omitting keeps the stored one.","type":"string","maxLength":128},"unsafe":{"description":"Show a warning page before redirecting.","type":"boolean"},"geo":{"description":"Geo-routing rules mapping a two-letter country code to a URL.","type":"object","propertyNames":{"type":"string","pattern":"^[A-Z]{2}$"},"additionalProperties":{"type":"string","maxLength":16384,"format":"uri"}},"tags":{"description":"Up to 10 normalized link tags, each 1-32 characters.","maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":32}}},"required":["url","slug"]},"ImportData":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"version":{"type":"string"},"exportedAt":{"type":"string"},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"links":{"minItems":1,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":16384,"format":"uri","description":"The target URL."},"slug":{"type":"string","maxLength":2048,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"comment":{"description":"Optional internal note.","type":"string","maxLength":2048},"expiration":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"title":{"description":"Overrides the title in the link preview.","type":"string","maxLength":256},"description":{"description":"Overrides the description in the link preview.","type":"string","maxLength":2048},"image":{"description":"Preview image: an uploaded key or an absolute http(s) URL.","type":"string"},"apple":{"description":"Apple App Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"google":{"description":"Google Play Store redirect URL.","type":"string","maxLength":16384,"format":"uri"},"cloaking":{"description":"Mask the destination URL behind the short link.","type":"boolean"},"redirectWithQuery":{"description":"Append incoming query parameters to the destination URL.","type":"boolean"},"proxy":{"description":"Reverse-proxy the destination instead of redirecting.","type":"boolean"},"password":{"type":"string","minLength":1,"maxLength":128,"description":"Password protection for the link."},"unsafe":{"description":"Show a warning page before redirecting.","type":"boolean"},"geo":{"description":"Geo-routing rules mapping a two-letter country code to a URL.","type":"object","propertyNames":{"type":"string","pattern":"^[A-Z]{2}$"},"additionalProperties":{"type":"string","maxLength":16384,"format":"uri"}},"tags":{"description":"Up to 10 normalized link tags, each 1-32 characters.","maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":32}},"id":{"type":"string","minLength":1,"maxLength":26},"createdAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updatedAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["url","slug"]}}},"required":["version","links"]},"ExactUrlSearch":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":16384,"format":"uri","description":"Normalized target URL to match exactly."},"limit":{"default":20,"description":"Maximum number of results, 1-1000.","type":"integer","minimum":1,"maximum":1000}},"required":["url"]},"DomainCreate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","maxLength":63,"pattern":"^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"},"slug":{"type":"string","maxLength":2048,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"url":{"type":"string","minLength":1,"maxLength":16384,"format":"uri"}},"required":["name"]},"DomainUpdate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","minLength":1},"status":{"type":"string","enum":["active","paused"]},"slug":{"type":"string","maxLength":2048,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}},"required":["id"]},"ApiKeyCreate":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64},"role":{"default":"member","type":"string","enum":["admin","power-user","member","viewer"]},"expiresAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["name"]}}}}