{"openapi":"3.1.0","info":{"title":"Custom Domain API","description":"\nCustom domains for multi-tenant SaaS. Applications register customer hostnames\nfor their workspaces, hand the returned DNS records to the customer, and are\ntold when the hostname is verified, certified and serving.\n\nApplications are registered by the operator (`custom-domain application create`)\nand receive credentials from the operator (`custom-domain credential issue`).\nThere is no self-service registration endpoint in v1. Every request is scoped\nto the application that owns the presented credential.\n\nThe endpoints under `/domains` without a version prefix are the legacy\nsingle-application API. They are deprecated and disabled by setting\n`ENABLE_LEGACY_API=false`.\n","version":"1.0.0"},"paths":{"/v1/domains":{"post":{"tags":["Domains"],"summary":"Register a hostname","description":"Claims an exact customer subdomain for a workspace of the calling application and returns the DNS records the customer must publish. The hostname is normalized before it is stored. A hostname can be live in only one application; a second claim anywhere returns `hostname_already_claimed`. When the application or the deployment already has as many live domains as its limit allows, the request returns `domain_limit_reached`; existing domains are unaffected.\n\nSend an `Idempotency-Key` header to make retries safe: a repeated key with the same body returns the original domain with status 200 and `Idempotent-Replayed: true`; a repeated key with a different body returns `idempotency_key_reused`. Keys are scoped to the application and expire after 24 hours.","operationId":"create_domain_v1_domains_post","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"description":"Client-chosen unique key that makes the create safe to retry.","title":"Idempotency-Key"},"description":"Client-chosen unique key that makes the create safe to retry."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainCreate"},"examples":{"registration":{"summary":"Register a workspace domain","value":{"hostname":"Forms.Customer.Example","reference":"ws_8f3a1c","metadata":{"plan":"pro"}}}}}}},"responses":{"201":{"description":"Domain registered; publish the returned DNS records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResource"},"examples":{"registration":{"summary":"Registration: waiting for DNS","value":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"pending_dns","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"pending"},{"type":"routing","status":"pending"},{"type":"certificate","status":"pending"},{"type":"origin","status":"pending"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T14:00:00Z"}}}}}},"401":{"description":"Missing, invalid, revoked or expired credential.","content":{"application/json":{"example":{"error":{"code":"unauthorized","message":"A valid application credential is required","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The application is suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid hostname, reference, metadata or idempotency key reuse.","content":{"application/json":{"examples":{"apex_not_supported":{"value":{"error":{"code":"apex_not_supported","message":"Only subdomains such as forms.example.com are supported; apex domains are not supported yet","details":{"field":"hostname"}}}},"idempotency_key_reused":{"value":{"error":{"code":"idempotency_key_reused","message":"Idempotency-Key was already used with a different request body","details":{}}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"200":{"description":"Replay of an earlier request with the same Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResource"}}}},"409":{"description":"The hostname is already claimed, or the application or deployment has reached its limit of live domains.","content":{"application/json":{"examples":{"hostname_already_claimed":{"value":{"error":{"code":"hostname_already_claimed","message":"forms.customer.example is already claimed","details":{}}}},"domain_limit_reached":{"value":{"error":{"code":"domain_limit_reached","message":"Application 'forms' has reached its limit of 200 live domains","details":{"scope":"application","limit":200,"live":200}}}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["Domains"],"summary":"List domains","description":"Lists the calling application's domains, newest last, with offset pagination. Filter by workspace `reference` and by `status`. Deleted domains are excluded unless `include_deleted=true`.","operationId":"list_domains_v1_domains_get","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"reference","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Reference"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/DomainStatus"},{"type":"null"}],"title":"Status"}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Deleted"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainPage"},"examples":{"mixed":{"summary":"One ready domain and one waiting for DNS","value":{"items":[{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"ready","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"routing","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"certificate","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"origin","status":"passing","observed_at":"2026-09-25T15:00:00Z"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T15:00:00Z"},{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"pending_dns","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"failing","error_code":"txt_record_not_found","message":"No TXT record named _custom-domain-challenge.forms.customer.example was found","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"routing","status":"failing","error_code":"cname_not_found","message":"forms.customer.example has no CNAME record","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"certificate","status":"pending"},{"type":"origin","status":"pending"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T14:05:00Z"}],"limit":50,"offset":0}}}}}},"401":{"description":"Missing, invalid, revoked or expired credential.","content":{"application/json":{"example":{"error":{"code":"unauthorized","message":"A valid application credential is required","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The application is suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/domains/{domain_id}":{"get":{"tags":["Domains"],"summary":"Get a domain","description":"Returns one domain of the calling application with its current checks. A domain that belongs to another application is reported as not found.","operationId":"get_domain_v1_domains__domain_id__get","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"domain_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Domain Id"}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Deleted"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResource"},"examples":{"waiting_for_dns":{"summary":"Waiting for DNS: records not found yet","value":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"pending_dns","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"failing","error_code":"txt_record_not_found","message":"No TXT record named _custom-domain-challenge.forms.customer.example was found","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"routing","status":"failing","error_code":"cname_not_found","message":"forms.customer.example has no CNAME record","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"certificate","status":"pending"},{"type":"origin","status":"pending"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T14:05:00Z"}},"ready":{"summary":"Ready and serving","value":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"ready","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"routing","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"certificate","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"origin","status":"passing","observed_at":"2026-09-25T15:00:00Z"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T15:00:00Z"}},"dns_drift":{"summary":"DNS drift: CNAME changed after readiness","value":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"attention_required","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"routing","status":"failing","error_code":"cname_target_mismatch","message":"CNAME points to old-host.example, expected acme.edge.example.net","observed_at":"2026-10-02T09:30:00Z","next_check_at":"2026-10-02T09:45:00Z"},{"type":"certificate","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"origin","status":"passing","observed_at":"2026-09-25T15:00:00Z"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-10-02T09:30:00Z"}}}}}},"401":{"description":"Missing, invalid, revoked or expired credential.","content":{"application/json":{"example":{"error":{"code":"unauthorized","message":"A valid application credential is required","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The application is suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"example":{"error":{"code":"domain_not_found","message":"domain_not_found","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"}}},"delete":{"tags":["Domains"],"summary":"Delete a domain","description":"Stops serving the hostname and revokes its ownership claim. The domain enters `deleting`, is excluded from listings, and its hostname can be registered again immediately (with new DNS records). Deleting an already deleted domain is a no-op.","operationId":"delete_domain_v1_domains__domain_id__delete","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"domain_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Domain Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResource"},"example":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"deleting","dns_records":[],"checks":[{"type":"ownership","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"routing","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"certificate","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"origin","status":"passing","observed_at":"2026-09-25T15:00:00Z"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-10-10T08:00:00Z","deleted_at":"2026-10-10T08:00:00Z"}}}},"401":{"description":"Missing, invalid, revoked or expired credential.","content":{"application/json":{"example":{"error":{"code":"unauthorized","message":"A valid application credential is required","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The application is suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"}}}},"/v1/domains/{domain_id}/checks":{"post":{"tags":["Domains"],"summary":"Request a recheck","description":"Asks the lifecycle worker to re-run ownership, routing, certificate and origin checks as soon as possible, for example after the customer fixed a DNS record. The response reflects the state before the recheck runs; poll the domain or subscribe to webhooks for the outcome.\n\nManual rechecks are rate limited: at most one per domain every 60 seconds and 60 per application per hour. Over the limit the response is `429 rate_limited` with a `Retry-After` header. A deleted domain cannot be rechecked and returns `409 invalid_status_transition`.","operationId":"request_recheck_v1_domains__domain_id__checks_post","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"domain_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Domain Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainResource"},"example":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"pending_dns","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"failing","error_code":"txt_record_not_found","message":"No TXT record named _custom-domain-challenge.forms.customer.example was found","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"routing","status":"failing","error_code":"cname_not_found","message":"forms.customer.example has no CNAME record","observed_at":"2026-09-25T14:05:00Z","next_check_at":"2026-09-25T14:10:00Z"},{"type":"certificate","status":"pending"},{"type":"origin","status":"pending"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T14:05:00Z"}}}},"401":{"description":"Missing, invalid, revoked or expired credential.","content":{"application/json":{"example":{"error":{"code":"unauthorized","message":"A valid application credential is required","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The application is suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many manual rechecks; wait for `Retry-After` seconds.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"content":{"application/json":{"example":{"error":{"code":"rate_limited","message":"This domain was rechecked less than 60 seconds ago","details":{"retry_after_seconds":42}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"description":"The domain is deleted and cannot be rechecked.","content":{"application/json":{"example":{"error":{"code":"invalid_status_transition","message":"Deleted domains are not rechecked","details":{}}},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks","operationId":"list_webhooks_v1_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WebhookResource"},"type":"array","title":"Response List Webhooks V1 Webhooks Get"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"ApplicationCredential":[]}]},"post":{"tags":["Webhooks"],"summary":"Subscribe to domain events","description":"Registers an endpoint for the calling application. The signing secret is returned once; deliveries carry `X-Custom-Domain-Signature: t=<unix>,v1=<hex HMAC-SHA256>` over `<t>.<body>`. The URL must be https and resolve to a public address.","operationId":"create_webhook_v1_webhooks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"ApplicationCredential":[]}]}},"/v1/webhooks/{webhook_id}":{"delete":{"tags":["Webhooks"],"summary":"Revoke a webhook","description":"Stops deliveries; pending deliveries are abandoned. History stays readable.","operationId":"revoke_webhook_v1_webhooks__webhook_id__delete","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResource"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{webhook_id}/rotate":{"post":{"tags":["Webhooks"],"summary":"Rotate the signing secret","description":"Issues a new secret and keeps signing with the previous one as well for 24 hours, so the consumer can switch without rejecting deliveries.","operationId":"rotate_webhook_v1_webhooks__webhook_id__rotate_post","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{webhook_id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Delivery history","operationId":"list_deliveries_v1_webhooks__webhook_id__deliveries_get","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"enum":["pending","delivered","abandoned"],"type":"string"},{"type":"null"}],"title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeliveryResource"},"title":"Response List Deliveries V1 Webhooks  Webhook Id  Deliveries Get"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{webhook_id}/deliveries/{delivery_id}/replay":{"post":{"tags":["Webhooks"],"summary":"Replay one delivery","description":"Queues the same payload again. Consumers must deduplicate by event `id`.","operationId":"replay_delivery_v1_webhooks__webhook_id__deliveries__delivery_id__replay_post","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Delivery Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryResource"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/webhooks/{webhook_id}/replay":{"post":{"tags":["Webhooks"],"summary":"Replay deliveries since a time","description":"Re-queues every delivery created at or after `since`, delivered or not: the recovery path after an outage on the consumer side. Consumers must deduplicate by event `id` and order by `created_at`.","operationId":"replay_since_v1_webhooks__webhook_id__replay_post","security":[{"ApplicationCredential":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}},{"name":"since","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"ISO 8601 timestamp","title":"Since"},"description":"ISO 8601 timestamp"}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResult"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"429":{"description":"Too many requests with an invalid credential from this client address (`V1_AUTH_FAILURES_PER_MINUTE`); retry after `Retry-After` seconds.","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/operator/v1/applications":{"get":{"tags":["Operator"],"summary":"List Applications","operationId":"list_applications_operator_v1_applications_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApplicationResource"},"type":"array","title":"Response List Applications Operator V1 Applications Get"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OperatorToken":[]}]},"post":{"tags":["Operator"],"summary":"Create Application","operationId":"create_application_operator_v1_applications_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OperatorToken":[]}]}},"/operator/v1/applications/{slug}":{"get":{"tags":["Operator"],"summary":"Get Application","operationId":"get_application_operator_v1_applications__slug__get","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Operator"],"summary":"Update Application","operationId":"update_application_operator_v1_applications__slug__patch","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Operator"],"summary":"Delete Application","operationId":"delete_application_operator_v1_applications__slug__delete","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"confirm","in":"query","required":false,"schema":{"type":"string","description":"Repeat the slug to confirm.","default":"","title":"Confirm"},"description":"Repeat the slug to confirm."},{"name":"delete_domains","in":"query","required":false,"schema":{"type":"boolean","description":"Also delete its live domains (refused without it).","default":false,"title":"Delete Domains"},"description":"Also delete its live domains (refused without it)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationDeleted"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/traffic":{"get":{"tags":["Operator"],"summary":"Application Traffic","description":"The application's proxied requests and response bytes per day, counted at the edge.","operationId":"application_traffic_operator_v1_applications__slug__traffic_get","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":400,"minimum":1,"description":"UTC days, today included.","default":30,"title":"Days"},"description":"UTC days, today included."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationTrafficResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/origins":{"get":{"tags":["Operator"],"summary":"List Origins","operationId":"list_origins_operator_v1_applications__slug__origins_get","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OriginResource"},"title":"Response List Origins Operator V1 Applications  Slug  Origins Get"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Operator"],"summary":"Register Origin","operationId":"register_origin_operator_v1_applications__slug__origins_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/origins/{origin_id}/verify":{"post":{"tags":["Operator"],"summary":"Verify Origin Endpoint","operationId":"verify_origin_endpoint_operator_v1_applications__slug__origins__origin_id__verify_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"origin_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Origin Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OriginVerify"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/origins/{origin_id}/activate":{"post":{"tags":["Operator"],"summary":"Activate Origin","operationId":"activate_origin_operator_v1_applications__slug__origins__origin_id__activate_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"origin_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Origin Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/origins/{origin_id}/retire":{"post":{"tags":["Operator"],"summary":"Retire Origin","operationId":"retire_origin_operator_v1_applications__slug__origins__origin_id__retire_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"origin_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Origin Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/origins/{origin_id}":{"delete":{"tags":["Operator"],"summary":"Delete Origin","operationId":"delete_origin_operator_v1_applications__slug__origins__origin_id__delete","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"origin_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Origin Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/assertion-keys":{"get":{"tags":["Operator"],"summary":"List Assertion Keys","description":"The application's own assertion keys (no secrets), and which one signs now.","operationId":"list_assertion_keys_operator_v1_applications__slug__assertion_keys_get","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssertionKeys"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Operator"],"summary":"Issue Assertion Key","description":"Issue the application's next assertion key; the secret is in this response only.","operationId":"issue_assertion_key_operator_v1_applications__slug__assertion_keys_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/AssertionKeyCreate"},{"type":"null"}],"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewAssertionKey"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/assertion-keys/{key_id}/revoke":{"post":{"tags":["Operator"],"summary":"Revoke Assertion Key","description":"Stop signing with a key now; the previous key, or the deployment key, takes over.","operationId":"revoke_assertion_key_operator_v1_applications__slug__assertion_keys__key_id__revoke_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssertionKeyResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/credentials":{"get":{"tags":["Operator"],"summary":"List Credentials","operationId":"list_credentials_operator_v1_applications__slug__credentials_get","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CredentialResource"},"title":"Response List Credentials Operator V1 Applications  Slug  Credentials Get"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Operator"],"summary":"Issue Credential","operationId":"issue_credential_operator_v1_applications__slug__credentials_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCredential"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/credentials/{credential_id}/rotate":{"post":{"tags":["Operator"],"summary":"Rotate Credential","operationId":"rotate_credential_operator_v1_applications__slug__credentials__credential_id__rotate_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Credential Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CredentialRotate"},{"type":"null"}],"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCredential"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/credentials/{credential_id}/revoke":{"post":{"tags":["Operator"],"summary":"Revoke Credential","operationId":"revoke_credential_operator_v1_applications__slug__credentials__credential_id__revoke_post","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Credential Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResource"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/applications/{slug}/credentials/{credential_id}":{"delete":{"tags":["Operator"],"summary":"Delete Credential","operationId":"delete_credential_operator_v1_applications__slug__credentials__credential_id__delete","security":[{"OperatorToken":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"credential_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Credential Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/operator/v1/token":{"put":{"tags":["Operator"],"summary":"Replace the operator token","description":"Sets a new operator token, effective at once on every API instance. Only its SHA-256 is stored, and the previous token (including `OPERATOR_API_TOKEN`) stops working. Use it to retire a token that was handed out at install time. `custom-domain operator reset-token` on the host makes `OPERATOR_API_TOKEN` valid again.","operationId":"set_operator_token_operator_v1_token_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperatorTokenSet"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OperatorToken":[]}]}},"/operator/v1/backup":{"get":{"tags":["Operator"],"summary":"Download a database backup","description":"Streams `pg_dump --format=custom` of the deployment's database; restore it with `pg_restore` (docs/operations.md). It contains claim tokens, credential hashes and webhook signing secrets: store it like a secrets file. Off (404) unless `OPERATOR_BACKUP=true`. PostgreSQL only; `409 backup_unavailable` otherwise. One at a time: `429` while another runs.","operationId":"backup_operator_v1_backup_get","responses":{"200":{"description":"Successful Response","content":{"application/octet-stream":{}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OperatorToken":[]}]}},"/operator/v1/doctor":{"get":{"tags":["Operator"],"summary":"Doctor","description":"The same checks as `custom-domain doctor`, for monitoring a deployment.","operationId":"doctor_operator_v1_doctor_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoctorReport"}}}},"401":{"description":"Missing or wrong operator token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The client address may not use it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found, or the operator API is off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The request is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many failed tokens from this client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OperatorToken":[]}]}}},"webhooks":{"domain.ready":{"post":{"summary":"The domain passed every check and is serving","description":"Sent when a domain enters `ready`. Deliveries carry `X-Custom-Domain-Signature: t=<unix time>,v1=<hex HMAC-SHA256>` computed over `<t>.<raw body>` with the application's webhook secret, which is distinct from its API credential. Reject deliveries older than five minutes and treat the event `id` as the deduplication key; events may arrive more than once and out of order.","operationId":"domain_readydomain_ready_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"example":{"id":"b7e2c1a0-9d8f-4e7a-b6c5-d4e3f2a1b0c9","type":"domain.ready","created_at":"2026-09-25T15:00:00Z","data":{"domain":{"id":"6f1c2d3e-4b5a-4c6d-8e9f-0a1b2c3d4e5f","hostname":"forms.customer.example","reference":"ws_8f3a1c","status":"ready","dns_records":[{"name":"_custom-domain-challenge.forms.customer.example","type":"TXT","value":"custom-domain-verify=Qm9vayBvZiB0aGUgZGVhZCwgY2hhcHRlciBzZXZlbg","purpose":"ownership","help":"Create a TXT record with exactly this name and value."},{"name":"forms.customer.example","type":"CNAME","value":"acme.edge.example.net","purpose":"routing","help":"Point the hostname at the target with a CNAME record."}],"checks":[{"type":"ownership","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"routing","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"certificate","status":"passing","observed_at":"2026-09-25T15:00:00Z"},{"type":"origin","status":"passing","observed_at":"2026-09-25T15:00:00Z"}],"metadata":{"plan":"pro"},"created_at":"2026-09-25T14:00:00Z","updated_at":"2026-09-25T15:00:00Z"}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"domain.attention_required":{"post":{"summary":"A previously satisfied check is failing","description":"Sent when a domain enters `attention_required`, for example on DNS drift. Deliveries carry `X-Custom-Domain-Signature: t=<unix time>,v1=<hex HMAC-SHA256>` computed over `<t>.<raw body>` with the application's webhook secret, which is distinct from its API credential. Reject deliveries older than five minutes and treat the event `id` as the deduplication key; events may arrive more than once and out of order.","operationId":"domain_attention_requireddomain_attention_required_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"domain.recovered":{"post":{"summary":"The domain returned to ready after attention was required","description":"Sent when a domain moves from `attention_required` back to `ready`. Deliveries carry `X-Custom-Domain-Signature: t=<unix time>,v1=<hex HMAC-SHA256>` computed over `<t>.<raw body>` with the application's webhook secret, which is distinct from its API credential. Reject deliveries older than five minutes and treat the event `id` as the deduplication key; events may arrive more than once and out of order.","operationId":"domain_recovereddomain_recovered_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"domain.deleted":{"post":{"summary":"The domain was deleted and stopped serving","description":"Sent when a domain is deleted. `dns_records` is empty. Deliveries carry `X-Custom-Domain-Signature: t=<unix time>,v1=<hex HMAC-SHA256>` computed over `<t>.<raw body>` with the application's webhook secret, which is distinct from its API credential. Reject deliveries older than five minutes and treat the event `id` as the deduplication key; events may arrive more than once and out of order.","operationId":"domain_deleteddomain_deleted_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ApplicationCreate":{"properties":{"slug":{"type":"string","maxLength":64,"title":"Slug","examples":["acme"]},"name":{"type":"string","maxLength":200,"title":"Name","examples":["Acme Forms"]},"cname_target":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"title":"Cname Target","description":"The name customers CNAME to. Defaults to EDGE_HOSTNAME.","examples":["edge.example.net"]}},"additionalProperties":false,"type":"object","required":["slug","name"],"title":"ApplicationCreate"},"ApplicationDeleted":{"properties":{"deleted":{"type":"string","title":"Deleted","description":"The slug the application had."},"live_domains_deleted":{"type":"integer","title":"Live Domains Deleted"}},"type":"object","required":["deleted","live_domains_deleted"],"title":"ApplicationDeleted"},"ApplicationResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"cname_target":{"type":"string","title":"Cname Target"},"workspace_probe":{"type":"boolean","title":"Workspace Probe"},"max_domains":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Domains","description":"The application's limit; null for none."},"live_domains":{"type":"integer","title":"Live Domains","description":"Registered and not deleted domains."},"rate_limit_per_minute":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Per Minute","description":"null for no limit"},"rate_limit_per_second":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Per Second","description":"null for no limit"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","slug","name","status","cname_target","workspace_probe","max_domains","live_domains","rate_limit_per_minute","rate_limit_per_second","created_at"],"title":"ApplicationResource"},"ApplicationTrafficResource":{"properties":{"application":{"type":"string","title":"Application"},"days":{"items":{"$ref":"#/components/schemas/TrafficDayResource"},"type":"array","title":"Days","description":"Oldest first; today is last and partial."},"requests":{"type":"integer","title":"Requests","description":"Total over the days listed."},"response_bytes":{"type":"integer","title":"Response Bytes","description":"Total over the days listed."}},"type":"object","required":["application","days","requests","response_bytes"],"title":"ApplicationTrafficResource"},"ApplicationUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name"},"cname_target":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"title":"Cname Target"},"reissue_claims":{"type":"boolean","title":"Reissue Claims","description":"With a new cname_target: re-issue the DNS records of every live domain still on the old one (they wait for DNS until their customers publish them).","default":false},"workspace_probe":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Workspace Probe","description":"Whether readiness requires the origin's workspace check."},"status":{"anyOf":[{"type":"string","enum":["active","suspended"]},{"type":"null"}],"title":"Status"},"rate_limit_per_minute":{"anyOf":[{"type":"integer","maximum":1000000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Minute","description":"Proxied requests per minute across the application's hostnames, at the edge; null lifts it, omit to leave it unchanged."},"rate_limit_per_second":{"anyOf":[{"type":"integer","maximum":1000000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Second","description":"The same, per second."},"max_domains":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Domains","description":"At most this many live domains; null removes the limit. Omit to leave it unchanged. Lowering it below the current count keeps existing domains working and refuses new ones with domain_limit_reached."}},"additionalProperties":false,"type":"object","title":"ApplicationUpdate"},"AssertionKeyCreate":{"properties":{"activate_in_hours":{"type":"number","maximum":720.0,"minimum":0.0,"title":"Activate In Hours","description":"When the key starts signing. Add it to the origin's keyring before then; 0 signs at once, which suits an application whose origin has no key yet.","default":24}},"additionalProperties":false,"type":"object","title":"AssertionKeyCreate"},"AssertionKeyResource":{"properties":{"key_id":{"type":"string","title":"Key Id","description":"The id in the assertion: v1.<key id>.<payload>.<mac>."},"state":{"type":"string","enum":["signing","next","previous","revoked"],"title":"State"},"active_from":{"type":"string","format":"date-time","title":"Active From"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["key_id","state","active_from","created_at","revoked_at"],"title":"AssertionKeyResource"},"AssertionKeys":{"properties":{"application_id":{"type":"string","format":"uuid","title":"Application Id","description":"The assertion's `app`: the id the origin compares with its own."},"signing":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signing","description":"The key id signing now, or null while the deployment key signs."},"keys":{"items":{"$ref":"#/components/schemas/AssertionKeyResource"},"type":"array","title":"Keys"}},"type":"object","required":["application_id","signing","keys"],"title":"AssertionKeys"},"CheckResult":{"properties":{"type":{"$ref":"#/components/schemas/CheckType"},"status":{"$ref":"#/components/schemas/CheckStatus"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code","description":"Stable machine-readable failure code when `status` is `failing`."},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"observed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Observed At"},"next_check_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Check At"}},"type":"object","required":["type","status"],"title":"CheckResult"},"CheckStatus":{"type":"string","enum":["pending","passing","failing"],"title":"CheckStatus"},"CheckType":{"type":"string","enum":["ownership","routing","certificate","origin"],"title":"CheckType"},"CredentialCreate":{"properties":{"label":{"type":"string","maxLength":100,"title":"Label","examples":["backend"]},"expires_in_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Expires In Days"}},"additionalProperties":false,"type":"object","required":["label"],"title":"CredentialCreate"},"CredentialResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"label":{"type":"string","title":"Label"},"key_prefix":{"type":"string","title":"Key Prefix"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","label","key_prefix","created_at","last_used_at","expires_at","revoked_at"],"title":"CredentialResource"},"CredentialRotate":{"properties":{"grace_hours":{"type":"integer","maximum":720.0,"minimum":0.0,"title":"Grace Hours","default":24}},"additionalProperties":false,"type":"object","title":"CredentialRotate"},"DeliveryResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"event_id":{"type":"string","format":"uuid","title":"Event Id"},"event_type":{"type":"string","title":"Event Type"},"domain_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Domain Id"},"state":{"type":"string","enum":["pending","delivered","abandoned"],"title":"State"},"attempts":{"type":"integer","title":"Attempts"},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Attempt At"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivered At"},"abandoned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Abandoned At"},"last_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Attempt At"},"last_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Status"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","event_id","event_type","domain_id","state","attempts","next_attempt_at","delivered_at","abandoned_at","last_attempt_at","last_status","last_error","created_at"],"title":"DeliveryResource"},"DnsRecord":{"properties":{"name":{"type":"string","title":"Name","description":"Fully qualified record name to create."},"type":{"type":"string","enum":["TXT","CNAME"],"title":"Type"},"value":{"type":"string","title":"Value"},"purpose":{"type":"string","enum":["ownership","routing"],"title":"Purpose","description":"`ownership` proves control of the hostname; `routing` sends traffic to the edge."},"help":{"type":"string","title":"Help","description":"Guidance for the customer's DNS console."}},"type":"object","required":["name","type","value","purpose","help"],"title":"DnsRecord"},"DoctorReport":{"properties":{"ok":{"type":"integer","title":"Ok"},"warn":{"type":"integer","title":"Warn"},"fail":{"type":"integer","title":"Fail"},"findings":{"items":{"$ref":"#/components/schemas/Finding"},"type":"array","title":"Findings"}},"type":"object","required":["ok","warn","fail","findings"],"title":"DoctorReport"},"DomainCreate":{"properties":{"hostname":{"type":"string","maxLength":253,"minLength":1,"title":"Hostname","description":"Exact customer subdomain. Normalized to lowercase punycode.","examples":["forms.customer.example"]},"reference":{"type":"string","maxLength":255,"minLength":1,"title":"Reference","description":"Opaque workspace identifier owned by the application. Returned verbatim.","examples":["ws_8f3a1c"]},"metadata":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional caller metadata, at most 32 scalar values, stored and echoed back.","examples":[{"owner":"user_42","plan":"pro"}]}},"additionalProperties":false,"type":"object","required":["hostname","reference"],"title":"DomainCreate","description":"Register a customer hostname for a workspace of the calling application."},"DomainPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/DomainResource"},"type":"array","title":"Items"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset","description":"Pass as `offset` to fetch the next page; null on the last page."}},"type":"object","required":["items","limit","offset"],"title":"DomainPage"},"DomainResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"hostname":{"type":"string","title":"Hostname","description":"Canonical hostname (lowercase, punycode)."},"reference":{"type":"string","title":"Reference"},"status":{"$ref":"#/components/schemas/DomainStatus"},"dns_records":{"items":{"$ref":"#/components/schemas/DnsRecord"},"type":"array","title":"Dns Records","description":"Records the customer must publish. Empty once the domain is deleted."},"checks":{"items":{"$ref":"#/components/schemas/CheckResult"},"type":"array","title":"Checks"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"deleted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deleted At"}},"type":"object","required":["id","hostname","reference","status","dns_records","checks","created_at","updated_at"],"title":"DomainResource"},"DomainStatus":{"type":"string","enum":["pending_dns","provisioning","ready","attention_required","suspended","deleting"],"title":"DomainStatus"},"ErrorBody":{"properties":{"code":{"type":"string","title":"Code","examples":["hostname_already_claimed"]},"message":{"type":"string","title":"Message"},"details":{"additionalProperties":true,"type":"object","title":"Details"}},"type":"object","required":["code","message"],"title":"ErrorBody"},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"type":"object","required":["error"],"title":"ErrorResponse"},"Finding":{"properties":{"check":{"type":"string","title":"Check"},"status":{"type":"string","enum":["ok","warn","fail"],"title":"Status"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["check","status","detail"],"title":"Finding"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"NewAssertionKey":{"properties":{"key_id":{"type":"string","title":"Key Id","description":"The id in the assertion: v1.<key id>.<payload>.<mac>."},"state":{"type":"string","enum":["signing","next","previous","revoked"],"title":"State"},"active_from":{"type":"string","format":"date-time","title":"Active From"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"application_id":{"type":"string","format":"uuid","title":"Application Id"},"secret":{"type":"string","title":"Secret","description":"The signing secret. Shown once; give it to the origin."}},"type":"object","required":["key_id","state","active_from","created_at","revoked_at","application_id","secret"],"title":"NewAssertionKey"},"NewCredential":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"label":{"type":"string","title":"Label"},"key_prefix":{"type":"string","title":"Key Prefix"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"secret":{"type":"string","title":"Secret","description":"The API key. Shown once; only its hash is stored."}},"type":"object","required":["id","label","key_prefix","created_at","last_used_at","expires_at","revoked_at","secret"],"title":"NewCredential"},"OperatorTokenSet":{"properties":{"token":{"type":"string","maxLength":256,"minLength":32,"title":"Token","description":"The new token: 32 to 256 letters, digits and . _ ~ + / = -"}},"additionalProperties":false,"type":"object","required":["token"],"title":"OperatorTokenSet"},"OriginCreate":{"properties":{"host":{"type":"string","maxLength":253,"title":"Host","examples":["app.acme.example"]},"scheme":{"type":"string","enum":["https","http"],"title":"Scheme","default":"https"},"port":{"anyOf":[{"type":"integer","maximum":65535.0,"minimum":1.0},{"type":"null"}],"title":"Port"}},"additionalProperties":false,"type":"object","required":["host"],"title":"OriginCreate"},"OriginResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"url":{"type":"string","title":"Url"},"status":{"type":"string","title":"Status"},"active":{"type":"boolean","title":"Active"},"verification_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Token","description":"Serve this as the plain-text body of verification_url, then verify."},"verification_url":{"type":"string","title":"Verification Url"},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"last_error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error Code"},"last_error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error Message"}},"type":"object","required":["id","url","status","active","verification_token","verification_url","verified_at","last_error_code","last_error_message"],"title":"OriginResource"},"OriginVerify":{"properties":{"activate":{"type":"boolean","title":"Activate","description":"Activate the origin once verified.","default":true}},"additionalProperties":false,"type":"object","title":"OriginVerify"},"ReplayResult":{"properties":{"requeued":{"type":"integer","title":"Requeued"}},"type":"object","required":["requeued"],"title":"ReplayResult"},"TrafficDayResource":{"properties":{"date":{"type":"string","format":"date","title":"Date","description":"A UTC day."},"requests":{"type":"integer","title":"Requests","description":"Proxied requests, including ones the edge refused."},"response_bytes":{"type":"integer","title":"Response Bytes","description":"Response body bytes sent to clients."}},"type":"object","required":["date","requests","response_bytes"],"title":"TrafficDayResource"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WebhookCreate":{"properties":{"url":{"type":"string","maxLength":2048,"minLength":1,"title":"Url","description":"Absolute https URL that receives POST deliveries. Must resolve to a public address.","examples":["https://app.acme.example/hooks/custom-domain"]},"events":{"items":{"type":"string","enum":["domain.ready","domain.attention_required","domain.recovered","domain.deleted"]},"type":"array","minItems":1,"title":"Events","description":"Event types to deliver.","examples":[["domain.ready","domain.deleted"]]}},"additionalProperties":false,"type":"object","required":["url","events"],"title":"WebhookCreate"},"WebhookCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"url":{"type":"string","title":"Url"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"active":{"type":"boolean","title":"Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"previous_secret_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Previous Secret Expires At","description":"Until when the previous secret still signs, after a rotation."},"secret":{"type":"string","title":"Secret","description":"Signing secret, shown once. Distinct from API credentials."}},"type":"object","required":["id","url","events","active","created_at","secret"],"title":"WebhookCreated"},"WebhookEvent":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Stable event id; deliveries of the same event share it."},"type":{"type":"string","enum":["domain.ready","domain.attention_required","domain.recovered","domain.deleted"],"title":"Type"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"data":{"$ref":"#/components/schemas/WebhookEventData"}},"type":"object","required":["id","type","created_at","data"],"title":"WebhookEvent","description":"Payload delivered to an application's webhook endpoint (delivery is tracked in #10)."},"WebhookEventData":{"properties":{"domain":{"$ref":"#/components/schemas/DomainResource"}},"type":"object","required":["domain"],"title":"WebhookEventData"},"WebhookResource":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"url":{"type":"string","title":"Url"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"active":{"type":"boolean","title":"Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"previous_secret_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Previous Secret Expires At","description":"Until when the previous secret still signs, after a rotation."}},"type":"object","required":["id","url","events","active","created_at"],"title":"WebhookResource"}},"securitySchemes":{"ApplicationCredential":{"type":"http","description":"Application credential issued by the operator with `custom-domain credential issue`. Send it as `Authorization: Bearer cd_...`. The application is derived from the credential; it is never taken from the request.","scheme":"bearer"},"OperatorToken":{"type":"http","description":"The deployment's OPERATOR_API_TOKEN, as `Authorization: Bearer <token>`.","scheme":"bearer"}}}}