{"openapi":"3.0.1","servers":[{"url":"https://dynalinks.app/api/v1","description":"Dynalinks"}],"info":{"description":"Dynalinks API for managing dynamic links and short links.\n","version":"1.0.0-oas3.1","title":"Dynalinks API","contact":{"email":"admins@dynalinks.app"}},"components":{"securitySchemes":{"ApiKeyQuery":{"type":"apiKey","name":"api_key","in":"query"},"ApiKeyHeader":{"type":"apiKey","name":"Authorization","in":"header","description":"Format: Authorization: Token {api_key}"}},"schemas":{"Link":{"type":"object","properties":{"name":{"type":"string","description":"Name of the dynamic link, displayed in the console user interface."},"path":{"type":"string","description":"You can retrieve parameters from the path in your iOS or Android apps and redirect your users to a specific screen."},"social_description":{"type":"string","description":"The content for the meta description tag is the concise summary that appears when the page is shared on social media."},"social_image_url":{"type":"string","description":"A URL to a unique image representing the content of the page."},"social_title":{"type":"string","description":"The content for the meta title tag is the title that appears when the page is shared on social media."},"url":{"type":"string","description":"This address will open when the user clicks on the link on a desktop."},"android_fallback_url":{"type":"string","description":"This address will open when the user clicks on the link on an Android device and the app is not installed."},"ios_fallback_url":{"type":"string","description":"This address will open when the user clicks on the link on an iOS device and the app is not installed."},"enable_forced_redirect":{"type":"boolean","description":"When set to true, bypass the app preview page for Dynalinks, redirecting users directly to the app or store. By default, the app preview page is enabled to ensure users are directed to the most suitable destination when opening links within apps."},"referrer":{"type":"string","description":"(Android only) Parameter for deferred deep linking which can be read using InstallReferrerClient library. This way, you can track the source of the install and attribute the install to the right source. Available on PRO plan only. **Important** - If your project has \"Link in Referrer\" feature enabled, this field will be ignored and the referrer parameter will be used exclusively for deferred deep linking (_url parameter). To track custom parameters when this feature is enabled, add them as query parameters to your link URL instead."},"ios_deferred_deep_linking_enabled":{"type":"boolean","description":"(iOS only) Parameter for deferred deep linking which can be read after installation. This way, you can track the source of the install and attribute the install to the right source. Available on PRO plan only."},"provider_token":{"type":"string","description":"(iOS only) Apple's provider token (pt parameter) for App Store campaign tracking. Used for affiliate programs and marketing campaigns. Available on PRO plan only. Must be provided together with campaign_token."},"campaign_token":{"type":"string","description":"(iOS only) Apple's campaign token (ct parameter) for App Store campaign tracking. Used to identify specific marketing campaigns. Available on PRO plan only. Must be provided together with provider_token."},"android_app":{"type":"object","properties":{"id":{"type":"string","description":"ID generated by Dynalinks for the Android app. You can find it listed under the ID column in the Android Apps section of the project's console. Not required if package_name is provided."},"package_name":{"type":"string","description":"The package name is the unique identifier for an Android app. Not required if id is provided.","example":"com.company.packagename"},"fingerprints":{"type":"array","description":"Pass this value only if you wish to create new application on the fly. If app is registered through the console then this field is not required.","example":"00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00","items":{"type":"string"}}},"oneOf":[{"required":["id"]},{"required":["package_name"]}]},"ios_app":{"type":"object","properties":{"id":{"type":"string","description":"ID generated by Dynalinks for the iOS app. You can find it listed under the ID column in the iOS Apps section of the project's console. Not required if bundle_id is provided."},"bundle_id":{"type":"string","description":"The App Bundle ID can be located in the General tab for your app's primary target in Xcode. Not required if id is provided."},"app_store_id":{"type":"string","description":"The App Store ID can be found in your app's URL, for example, https://itunes.apple.com/us/app/yourapp/id123456789. Pass this value only if you wish to create new application on the fly. If app is registered through the console then this field is not required."},"team_id":{"type":"string","description":"You can find your Team ID in the Apple Member Center under the provisioning profile. Pass this value only if you wish to create new application on the fly. If app is registered through the console then this field is not required."}},"oneOf":[{"required":["id"]},{"required":["bundle_id"]}]}}},"LinkResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the link"},"name":{"type":"string"},"path":{"type":"string"},"url":{"type":"string"},"social_description":{"type":"string"},"social_image_url":{"type":"string"},"social_title":{"type":"string"},"shortened_path":{"type":"string"},"android_fallback_url":{"type":"string"},"ios_fallback_url":{"type":"string"},"enable_forced_redirect":{"type":"boolean"},"referrer":{"type":"string"},"ios_deferred_deep_linking_enabled":{"type":"boolean"},"provider_token":{"type":"string"},"campaign_token":{"type":"string"},"android_app_id":{"type":"string"},"ios_app_id":{"type":"string"},"clicks":{"type":"integer","description":"Number of clicks/views for this link"}}},"ShortLink":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL to shorten","example":"https://yourproject.dynalinks.app/someLongPath"},"prefix":{"type":"string","description":"Prefix for the shortened link. Your link will be shortened to `{prefix}{randomCharacters}`. Rarely used.","example":"myPrefix/"}}},"ShortLinkResolve":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL to shorten","example":"https://yourproject.dynalinks.app/vs5r"}}},"ApiKey":{"type":"object","properties":{"scopes":{"type":"array","items":{"type":"string","enum":["links.show","links.index","links.create","links.update","links.destroy","short_links.create"]},"description":"Array of scopes that define what actions this API key can perform","example":["links.show","links.create"]}}},"ApiKeyResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the API key"},"scopes":{"type":"array","items":{"type":"string"},"description":"Array of scopes assigned to this API key"},"token":{"type":"string","description":"The API key token"},"created_at":{"type":"string","format":"date-time","description":"When the API key was created"},"updated_at":{"type":"string","format":"date-time","description":"When the API key was last updated"}}},"Project":{"type":"object","properties":{"name":{"type":"string","description":"Name of the project"},"subdomain":{"type":"string","description":"Subdomain for the project (e.g., 'myproject' creates myproject.dynalinks.app)"},"custom_domain":{"type":"string","description":"Custom domain for the project"}}},"ProjectResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the project"},"name":{"type":"string","description":"Name of the project"},"subdomain":{"type":"string","description":"Subdomain for the project"},"custom_domain":{"type":"string","description":"Custom domain for the project"},"custom_domain_verified":{"type":"boolean","description":"Whether the custom domain is verified"},"links_count":{"type":"integer","description":"Number of links in the project"}}},"IosApp":{"type":"object","properties":{"name":{"type":"string","description":"Name of the iOS app"},"bundle_id":{"type":"string","description":"The bundle identifier for the iOS app","pattern":"^[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"},"team_id":{"type":"string","description":"Apple Developer Team ID (10 characters)","minLength":10,"maxLength":10},"app_store_id":{"type":"string","description":"App Store ID for the app"},"custom_scheme":{"type":"string","description":"Custom URL scheme for Facebook App Links (al:ios:url meta tags)"}}},"IosAppResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the iOS app"},"name":{"type":"string","description":"Name of the iOS app"},"bundle_id":{"type":"string","description":"The bundle identifier for the iOS app"},"team_id":{"type":"string","description":"Apple Developer Team ID"},"app_store_id":{"type":"string","description":"App Store ID for the app"},"custom_scheme":{"type":"string","description":"Custom URL scheme for Facebook App Links (al:ios:url meta tags)"}}},"AndroidApp":{"type":"object","properties":{"name":{"type":"string","description":"Name of the Android app"},"package_name":{"type":"string","description":"The package name for the Android app","pattern":"^([A-Za-z]{1}[A-Za-z\\d_]*\\.)+[A-Za-z][A-Za-z\\d_]*$"},"fingerprints":{"type":"array","items":{"type":"string","pattern":"^([A-Fa-f0-9]{2}:)+[A-Fa-f0-9]{2}$"},"description":"Array of SHA-256 fingerprints for the app","minItems":1},"custom_scheme":{"type":"string","description":"Custom URL scheme for Facebook App Links (al:android:url meta tags)"}}},"AndroidAppResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the Android app"},"name":{"type":"string","description":"Name of the Android app"},"package_name":{"type":"string","description":"The package name for the Android app"},"fingerprints":{"type":"array","items":{"type":"string"},"description":"Array of SHA-256 fingerprints for the app"},"custom_scheme":{"type":"string","description":"Custom URL scheme for Facebook App Links (al:android:url meta tags)"}}},"PageTemplateDraft":{"type":"object","properties":{"body":{"type":"string","description":"Liquid and HTML for the page body, at most 65,536 bytes (UTF-8, so fewer characters if you\nuse non-ASCII text). Must include `{% store_buttons %}` at the top level. Omit to keep the\ncurrent value; send an empty string to clear it. `null` is rejected.\n"},"css":{"type":"string","description":"Plain CSS for the page, at most 32,768 bytes. Omit to keep the current value; send an empty\nstring to clear it. `null` is rejected.\n"}}},"PageTemplateVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the version"},"published_at":{"type":"string","format":"date-time","description":"When the version was published"},"live":{"type":"boolean","description":"Whether this is the version links currently show"}}},"PageTemplateVersionWithContent":{"allOf":[{"$ref":"#/components/schemas/PageTemplateVersion"},{"type":"object","properties":{"body":{"type":"string","description":"Liquid and HTML of the published body"},"css":{"type":"string","description":"CSS of the published version"}}}]},"PageTemplateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID of the page template"},"body":{"type":"string","description":"Body of the draft"},"css":{"type":"string","description":"CSS of the draft"},"unpublished_changes":{"type":"boolean","description":"Whether the draft differs from the live version"},"live_version":{"type":"object","nullable":true,"description":"The version links currently show, or null if nothing is published","allOf":[{"$ref":"#/components/schemas/PageTemplateVersionWithContent"}]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"PageTemplateErrors":{"type":"object","properties":{"error":{"type":"string","description":"All problems in one message"},"errors":{"type":"array","description":"Each problem, with the field and line it is on","items":{"type":"object","properties":{"field":{"type":"string","enum":["body","css"]},"line":{"type":"integer","nullable":true,"description":"Line in the field, when known"},"message":{"type":"string"}}}}}}}},"security":[{"ApiKeyHeader":[]},{"ApiKeyQuery":[]}],"tags":[{"name":"Links","description":"Create, update, look up and delete dynamic links."},{"name":"Short links","description":"Shorten long URLs and resolve short links back to their target."},{"name":"iOS apps","description":"Manage the iOS apps that links open."},{"name":"Android apps","description":"Manage the Android apps that links open."},{"name":"Projects","description":"Manage projects. Requires a master API key. Experimental: the request and response shapes may still change."},{"name":"API keys","description":"Manage a project's API keys. Requires a master API key. Experimental: the request and response shapes may still change."},{"name":"Page templates","description":"Manage the page template shown on link preview pages. Requires page-template access, enabled per project by Dynalinks. Experimental: the request and response shapes may still change."}],"paths":{"/links":{"get":{"operationId":"listLinks","summary":"List all links","tags":["Links"],"parameters":[{"name":"limit","in":"query","description":"Number of links to return per page","required":false,"schema":{"type":"integer","default":20}},{"name":"page","in":"query","description":"Page number to return","required":false,"schema":{"type":"integer","default":1}},{"name":"q[path_eq]","in":"query","description":"Use it if you want to check if the path is already taken.","example":"myPath","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of links","content":{"application/json":{"schema":{"type":"object","properties":{"links":{"type":"array","items":{"$ref":"#/components/schemas/LinkResponse"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Path has already been taken"}}}}}},"post":{"operationId":"createLink","summary":"Create a new link","description":"Creates a new link for the project.\n\n**Rate Limit**: 600 requests per minute.\n","tags":["Links"],"requestBody":{"description":"Link object to be created","required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Link"},{"type":"object","properties":{"options":{"type":"object","description":"Additional metadata for the link configuration.","example":{"shorten":true},"properties":{"shorten":{"type":"boolean","description":"Whether to shorten the link or not. If set to true, the link will contain non-empty `shortened_path` field in the response.","default":false}}}}}]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"},"example":{"id":1,"name":"Example Link","path":"example-link","url":"http://example.com","social_description":"Example description","social_image_url":"http://example.com/image.jpg","social_title":"Example Title"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"application/json content type is required by the requested endpoint"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Path has already been taken"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Rate limit exceeded. Too many requests."}}}}}}},"/links/upsert":{"post":{"operationId":"upsertLink","summary":"Create or update a link","description":"Creates a new link or updates an existing one if a link with the same path already exists.\n\n**Rate Limit**: 600 requests per minute.\n","tags":["Links"],"requestBody":{"description":"Link object to be created or updated","required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Link"},{"type":"object","properties":{"options":{"type":"object","description":"Additional metadata for the link configuration.","example":{"shorten":true},"properties":{"shorten":{"type":"boolean","description":"Whether to shorten the link or not. If set to true and the link is new, it will be shortened.","default":false}}}}}]}}}},"responses":{"200":{"description":"Link updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"}}}},"201":{"description":"Link created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Rate limit exceeded. Too many requests."}}}}}}},"/links/{id}":{"patch":{"operationId":"updateLink","summary":"Update an existing link","description":"Updates an existing link.\n\n**Rate Limit**: 600 requests per minute per API key\n","tags":["Links"],"parameters":[{"name":"id","in":"path","description":"ID of the link to update","required":true,"schema":{"type":"integer"}}],"requestBody":{"description":"Fields to update","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"responses":{"200":{"description":"Link updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"},"example":{"id":1,"name":"Updated Link","path":"updated-link","url":"http://updatedexample.com","social_description":"Updated description","social_image_url":"http://updatedexample.com/image.jpg","social_title":"Updated Title"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Invalid request parameters"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Link not found"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Path has already been taken"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Rate limit exceeded. Too many requests."}}}}}},"get":{"operationId":"getLink","summary":"Get a link by ID","tags":["Links"],"parameters":[{"name":"id","in":"path","description":"ID of the link to get","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Link found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"},"example":{"id":1,"name":"Example Link"}}}},"404":{"description":"Not Found"}}},"delete":{"operationId":"deleteLink","summary":"Delete a link by ID","tags":["Links"],"parameters":[{"name":"id","in":"path","description":"UUID of the link to delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Link deleted successfully"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"404":{"description":"Link not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Link not found"}}}}}}},"/short_links":{"post":{"operationId":"createShortLink","summary":"Shorten a link","description":"Creates a shortened link for the given URL.\n\n**Rate Limit**: 600 requests per minute.\n","tags":["Short links"],"requestBody":{"description":"URL to your dynalink which should be shortened","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLink"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"},"example":{"id":1,"name":"Example Link","shortened_path":"a4b2c"}}}},"404":{"description":"Link with given URL not found"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"examples":{"missing_api_key":{"value":{"error":"Missing api_key"}},"invalid_api_key":{"value":{"error":"You need to be on a pro plan to use this feature"}}}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Rate limit exceeded. Too many requests."}}}}}}},"/short_links/resolve":{"post":{"operationId":"resolveShortLink","summary":"Resolve a short link to full path","description":"Resolve a short link to full path. It's meant to be used on client side. API key is not required. You can use `path` from the response to read parameters from the path in your iOS or Android apps and redirect your users to a specific screen.","security":[],"tags":["Short links"],"requestBody":{"description":"Shortened path to resolve","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLinkResolve"}}}},"responses":{"200":{"description":"Link found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkResponse"},"example":{"id":1,"name":"Example Link","path":"longOriginalPath"}}}},"404":{"description":"Not Found"}}}},"/api_keys":{"get":{"operationId":"listApiKeys","summary":"List API keys for a project","tags":["API keys"],"parameters":[{"name":"project_id","in":"query","description":"UUID of the project to list API keys for","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Number of API keys to return per page","required":false,"schema":{"type":"integer","default":20}},{"name":"page","in":"query","description":"Page number to return","required":false,"schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"A list of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"api_keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyResponse"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}}},"post":{"operationId":"createApiKey","summary":"Create a new API key for a project","tags":["API keys"],"parameters":[{"name":"project_id","in":"query","description":"UUID of the project to create API key for","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"API key object to be created","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"}}}}}},"responses":{"201":{"description":"API key created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"},"422":{"description":"Unprocessable Entity"}}}},"/api_keys/{id}":{"get":{"operationId":"getApiKey","summary":"Get an API key by ID","tags":["API keys"],"parameters":[{"name":"id","in":"path","description":"UUID of the API key","required":true,"schema":{"type":"string"}},{"name":"project_id","in":"query","description":"UUID of the project","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"API key or project not found"}}},"patch":{"operationId":"updateApiKey","summary":"Update an API key","tags":["API keys"],"parameters":[{"name":"id","in":"path","description":"UUID of the API key","required":true,"schema":{"type":"string"}},{"name":"project_id","in":"query","description":"UUID of the project","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Fields to update","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"}}}}}},"responses":{"200":{"description":"API key updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized"},"404":{"description":"API key or project not found"},"422":{"description":"Unprocessable Entity"}}},"delete":{"operationId":"deleteApiKey","summary":"Delete an API key","tags":["API keys"],"parameters":[{"name":"id","in":"path","description":"UUID of the API key","required":true,"schema":{"type":"string"}},{"name":"project_id","in":"query","description":"UUID of the project","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"API key deleted successfully"},"401":{"description":"Unauthorized"},"404":{"description":"API key or project not found"}}}},"/projects":{"get":{"operationId":"listProjects","summary":"List projects","tags":["Projects"],"parameters":[{"name":"limit","in":"query","description":"Number of projects to return per page","required":false,"schema":{"type":"integer","default":20}},{"name":"page","in":"query","description":"Page number to return","required":false,"schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"A list of projects","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/ProjectResponse"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}}}},"post":{"operationId":"createProject","summary":"Create a new project","tags":["Projects"],"requestBody":{"description":"Project object to be created","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"}}}}}},"responses":{"201":{"description":"Project created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My Project","subdomain":"myproject","custom_domain":null,"custom_domain_verified":false,"links_count":0}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"application/json content type is required by the requested endpoint"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Subdomain has already been taken"}}}}}}},"/projects/{id}":{"get":{"operationId":"getProject","summary":"Get a project by ID","tags":["Projects"],"parameters":[{"name":"id","in":"path","description":"UUID of the project to get","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Project found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My Project","subdomain":"myproject","custom_domain":"example.com","custom_domain_verified":true,"links_count":25}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}}},"patch":{"operationId":"updateProject","summary":"Update an existing project","tags":["Projects"],"parameters":[{"name":"id","in":"path","description":"UUID of the project to update","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Fields to update","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"}}}}}},"responses":{"200":{"description":"Project updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Updated Project","subdomain":"updatedproject","custom_domain":"newdomain.com","custom_domain_verified":false,"links_count":25}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Invalid request parameters"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Project not found"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Subdomain has already been taken"}}}}}},"delete":{"operationId":"deleteProject","summary":"Delete a project","tags":["Projects"],"parameters":[{"name":"id","in":"path","description":"UUID of the project to delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Project deleted successfully"},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}}}},"/projects/{id}/verify_custom_domain":{"get":{"operationId":"verifyProjectCustomDomain","summary":"Verify custom domain for a project","description":"Verifies the custom domain configuration for a project by checking DNS records","tags":["Projects"],"parameters":[{"name":"id","in":"path","description":"UUID of the project","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Domain verification completed","content":{"application/json":{"schema":{"type":"object","properties":{"custom_domain":{"type":"string","description":"The custom domain that was verified"},"custom_domain_verified":{"type":"boolean","description":"Current verification status of the domain after running verification"}}},"example":{"custom_domain":"example.com","custom_domain_verified":true}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"No custom domain configured for this project"}}}}}}},"/ios_apps":{"get":{"operationId":"listIosApps","summary":"List iOS apps","tags":["iOS apps"],"parameters":[{"name":"limit","in":"query","description":"Number of iOS apps to return per page","required":false,"schema":{"type":"integer","default":20}},{"name":"page","in":"query","description":"Page number to return","required":false,"schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"A list of iOS apps","content":{"application/json":{"schema":{"type":"object","properties":{"ios_apps":{"type":"array","items":{"$ref":"#/components/schemas/IosAppResponse"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}}}},"post":{"operationId":"createIosApp","summary":"Create a new iOS app","tags":["iOS apps"],"requestBody":{"description":"iOS app object to be created","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ios_app":{"$ref":"#/components/schemas/IosApp"}}}}}},"responses":{"201":{"description":"iOS app created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IosAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My iOS App","bundle_id":"com.mycompany.myapp","team_id":"ABCD123456","app_store_id":"123456789"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"application/json content type is required by the requested endpoint"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Bundle has already been taken"}}}}}}},"/ios_apps/{id}":{"get":{"operationId":"getIosApp","summary":"Get an iOS app by ID","tags":["iOS apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the iOS app to get","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"iOS app found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IosAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My iOS App","bundle_id":"com.mycompany.myapp","team_id":"ABCD123456","app_store_id":"123456789"}}}},"401":{"description":"Unauthorized"},"404":{"description":"iOS app not found"}}},"patch":{"operationId":"updateIosApp","summary":"Update an existing iOS app","tags":["iOS apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the iOS app to update","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Fields to update","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ios_app":{"$ref":"#/components/schemas/IosApp"}}}}}},"responses":{"200":{"description":"iOS app updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IosAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Updated iOS App","bundle_id":"com.mycompany.updatedapp","team_id":"EFGH789012","app_store_id":"987654321"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Invalid request parameters"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"iOS app not found"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Bundle has already been taken"}}}}}},"delete":{"operationId":"deleteIosApp","summary":"Delete an iOS app","tags":["iOS apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the iOS app to delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"iOS app deleted successfully"},"401":{"description":"Unauthorized"},"404":{"description":"iOS app not found"}}}},"/android_apps":{"get":{"operationId":"listAndroidApps","summary":"List Android apps","tags":["Android apps"],"parameters":[{"name":"limit","in":"query","description":"Number of Android apps to return per page","required":false,"schema":{"type":"integer","default":20}},{"name":"page","in":"query","description":"Page number to return","required":false,"schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"A list of Android apps","content":{"application/json":{"schema":{"type":"object","properties":{"android_apps":{"type":"array","items":{"$ref":"#/components/schemas/AndroidAppResponse"}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}}}},"post":{"operationId":"createAndroidApp","summary":"Create a new Android app","tags":["Android apps"],"requestBody":{"description":"Android app object to be created","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"android_app":{"$ref":"#/components/schemas/AndroidApp"}}}}}},"responses":{"201":{"description":"Android app created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My Android App","package_name":"com.mycompany.myapp","fingerprints":["AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"application/json content type is required by the requested endpoint"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Package name has already been taken"}}}}}}},"/android_apps/{id}":{"get":{"operationId":"getAndroidApp","summary":"Get an Android app by ID","tags":["Android apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the Android app to get","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Android app found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"My Android App","package_name":"com.mycompany.myapp","fingerprints":["AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD"]}}}},"401":{"description":"Unauthorized"},"404":{"description":"Android app not found"}}},"patch":{"operationId":"updateAndroidApp","summary":"Update an existing Android app","tags":["Android apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the Android app to update","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Fields to update","required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"android_app":{"$ref":"#/components/schemas/AndroidApp"}}}}}},"responses":{"200":{"description":"Android app updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AndroidAppResponse"},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Updated Android App","package_name":"com.mycompany.updatedapp","fingerprints":["12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Invalid request parameters"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing or invalid api_key"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Android app not found"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Validation failed: Package name has already been taken"}}}}}},"delete":{"operationId":"deleteAndroidApp","summary":"Delete an Android app","tags":["Android apps"],"parameters":[{"name":"id","in":"path","description":"UUID of the Android app to delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Android app deleted successfully"},"401":{"description":"Unauthorized"},"404":{"description":"Android app not found"}}}},"/links/{id}/qr":{"get":{"operationId":"getLinkQrCode","summary":"Generate QR code for a link","description":"Generates a QR code for the specified link. The QR code encodes the full URL of the link.\n\n**Note**: This feature is available for PRO projects only.\n","tags":["Links"],"parameters":[{"name":"id","in":"path","description":"UUID of the link to generate QR code for","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","description":"QR code image format","required":false,"schema":{"type":"string","enum":["svg","png"],"default":"svg"}},{"name":"size","in":"query","description":"QR code size in pixels (for PNG format)","required":false,"schema":{"type":"integer","minimum":100,"maximum":1000,"default":300}},{"name":"offset","in":"query","description":"Border offset in SVG units (one module = 11 units, SVG format only)","required":false,"schema":{"type":"integer","minimum":0,"maximum":50,"default":0}}],"responses":{"200":{"description":"QR code generated successfully","content":{"image/svg+xml":{"schema":{"type":"string","description":"SVG QR code"}},"image/png":{"schema":{"type":"string","format":"binary","description":"PNG QR code image"}}}},"403":{"description":"Forbidden - QR code generation is available for PRO projects only","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"QR code generation is available for PRO projects only"}}}},"404":{"description":"Link not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Link not found"}}}},"400":{"description":"Bad Request - Invalid format","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Unsupported format. Use 'png' or 'svg'"}}}}}}},"/page_template":{"get":{"operationId":"getPageTemplate","summary":"Get the page template","description":"Returns the project's page template: the draft and the live version links currently show.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.show` scope.\n","tags":["Page templates"],"responses":{"200":{"description":"Page template found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"},"example":{"id":"0199e2a8-6f3b-7c1e-9a4d-2b8f6c1d3e5a","body":"<div class=\"page\">{{ link.title }}</div>\n{% store_buttons %}","css":".page { color: #111; }","unpublished_changes":true,"live_version":{"id":"0199e2a9-1a2b-7c3d-8e4f-5a6b7c8d9e0f","published_at":"2026-10-12T09:30:00.000Z","live":true,"body":"<div>{{ link.title }}</div>\n{% store_buttons %}","css":""},"created_at":"2026-10-10T08:00:00.000Z","updated_at":"2026-10-12T10:00:00.000Z"}}}},"401":{"description":"Unauthorized, or the project can't use page templates","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Page templates require a Pro plan."}}}},"404":{"description":"The project has no page template","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Page template not found"}}}}}},"patch":{"operationId":"updatePageTemplate","summary":"Save the page template draft","description":"Saves the draft. Creates the page template on the first save (201). Saving does not change\nthe live page; publish the draft for that. Fields you omit keep their current value.\n\nThe draft is validated: Liquid syntax, the required top-level `{% store_buttons %}` tag, the\nallowed HTML and CSS, the page's Content Security Policy, and the size limits (body 65,536\nbytes, CSS 32,768 bytes). Problems are returned with the field and line they are on.\n\nSaving, publishing and previewing share a limit of 60 requests per minute per API key.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.update` scope.\n","tags":["Page templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateDraft"},"example":{"body":"<div class=\"page\">{{ link.title }}</div>\n{% store_buttons %}","css":".page { color: #111; }"}}}},"responses":{"200":{"description":"Draft saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"}}}},"201":{"description":"Page template created with the draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"}}}},"400":{"description":"Neither body nor css was sent, or one of them is not a string","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"body or css is required"}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"422":{"description":"The draft is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateErrors"},"example":{"error":"Body: <script> is not allowed in a page template (line 3)","errors":[{"field":"body","line":3,"message":"<script> is not allowed in a page template"}]}}}}}}},"/page_template/publish":{"post":{"operationId":"publishPageTemplate","summary":"Publish the page template draft","description":"Publishes the draft as a new version. **This changes the page every link in the project shows.**\nSend `body` and/or `css` to save them first, as with `PATCH /page_template`. The last 20\nversions are kept. Versions published through the API are recorded as published by the\nproject owner.\n\nThe request body is optional. When you send one, send `Content-Type: application/json`.\nSaving, publishing and previewing share a limit of 60 requests per minute per API key.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.publish` scope. API keys with no scopes have full\naccess, so they can publish too. The `page_templates.publish` scope is enough to save a posted\n`body` or `css` here; `page_templates.update` is not needed.\n","tags":["Page templates"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateDraft"}}}},"responses":{"200":{"description":"Draft published","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"422":{"description":"The draft is blank or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateErrors"},"example":{"error":"Body: can't be blank","errors":[{"field":"body","line":null,"message":"can't be blank"}]}}}}}}},"/page_template/unpublish":{"post":{"operationId":"unpublishPageTemplate","summary":"Unpublish the page template","description":"Stops serving the page template. **This changes the page every link in the project shows:**\nlinks go back to the default page (or a legacy custom template, if the project has one).\nThe draft and the versions are kept, so you can publish again at any time.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.publish` scope. API keys with no scopes have full\naccess, so they can unpublish too.\n","tags":["Page templates"],"responses":{"200":{"description":"Page template unpublished; `live_version` is null","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"404":{"description":"The project has no page template"}}}},"/page_template/preview":{"post":{"operationId":"previewPageTemplate","summary":"Preview the page template","description":"Renders the full link page as HTML, without saving anything. Renders the posted `body` and\n`css`; whatever is omitted comes from the saved draft (or the starter template if the saved\ndraft is empty or the project has no page template). The page is rendered for a sample link,\nunless you pass `link_id`. The preview never redirects and never collects a fingerprint.\n\nAsset URLs in the HTML are absolute, so it can be shown in a webview or a `srcdoc` iframe.\nThe HTML includes our page scripts, so show it in a sandboxed iframe\n(`<iframe sandbox=\"allow-scripts\" srcdoc=\"...\">`) to keep them out of your own origin.\n\nThe request body is optional. When you send one, send `Content-Type: application/json`.\nSaving, publishing and previewing share a limit of 60 requests per minute per API key.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.show` scope. Previewing with `link_id` also needs the\n`links.show` scope.\n","tags":["Page templates"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PageTemplateDraft"},{"type":"object","properties":{"platform":{"type":"string","enum":["ios","android","desktop"],"default":"ios","description":"Device the page is rendered for"},"link_id":{"type":"string","description":"UUID of a link in the project to render the page for. Needs the `links.show` scope. Defaults to a sample link."}}}]},"example":{"body":"<h1>{{ link.title }}</h1>\n{% store_buttons %}","platform":"android"}}}},"responses":{"200":{"description":"The rendered page","content":{"application/json":{"schema":{"type":"object","properties":{"html":{"type":"string"}}},"example":{"html":"<!DOCTYPE html>\n<html>\n  <head>...</head>\n  <body>...</body>\n</html>"}}}},"400":{"description":"Unknown platform, or link_id, platform, body or css is not a string"},"401":{"description":"Unauthorized, or the project can't use page templates"},"404":{"description":"Link not found"},"422":{"description":"The draft is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateErrors"}}}}}}},"/page_template/versions":{"get":{"operationId":"listPageTemplateVersions","summary":"List page template versions","description":"Lists the kept published versions (up to 20), newest first, marking the live one. Bodies and\nCSS are left out; get a single version for them.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.show` scope.\n","tags":["Page templates"],"responses":{"200":{"description":"The versions","content":{"application/json":{"schema":{"type":"object","properties":{"versions":{"type":"array","items":{"$ref":"#/components/schemas/PageTemplateVersion"}}}},"example":{"versions":[{"id":"0199e2a9-1a2b-7c3d-8e4f-5a6b7c8d9e0f","published_at":"2026-10-12T09:30:00.000Z","live":true},{"id":"0199e1f0-3c4d-7e5f-9a0b-1c2d3e4f5a6b","published_at":"2026-10-11T14:00:00.000Z","live":false}]}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"404":{"description":"The project has no page template"}}}},"/page_template/versions/{id}":{"get":{"operationId":"getPageTemplateVersion","summary":"Get a page template version","description":"Returns one published version with its body and CSS.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.show` scope.\n","tags":["Page templates"],"parameters":[{"name":"id","in":"path","description":"UUID of the version","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Version found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateVersionWithContent"},"example":{"id":"0199e2a9-1a2b-7c3d-8e4f-5a6b7c8d9e0f","published_at":"2026-10-12T09:30:00.000Z","live":true,"body":"<div>{{ link.title }}</div>\n{% store_buttons %}","css":""}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"404":{"description":"Page template or version not found"}}}},"/page_template/versions/{id}/restore":{"post":{"operationId":"restorePageTemplateVersion","summary":"Restore a page template version","description":"Copies the version into the draft. Does not publish it, so the live page is unchanged until\nyou publish.\n\n**Requirements**: a Pro plan, page templates enabled for the project, and an API key of a project\nowner or manager with the `page_templates.update` scope.\n","tags":["Page templates"],"parameters":[{"name":"id","in":"path","description":"UUID of the version to restore","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Version copied into the draft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageTemplateResponse"}}}},"401":{"description":"Unauthorized, or the project can't use page templates"},"404":{"description":"Page template or version not found"}}}}}}