Assets: domains, sites, hosting
What an agency looks after on a client’s behalf, and the four services it reads that from: the registrar, the DNS zone, the monitor and the site itself.
91 endpoints across 7 groups. A permission written module.resource.action:own is scoped: :own covers rows that are yours, :any covers everyone’s, and :any satisfies a check for :own.
domains
Section titled “domains”| Endpoint | Permission |
|---|---|
GET /domains | domains.domain.read |
POST /domains | domains.domain.write |
GET /domains/{domain_id} | domains.domain.read |
PATCH /domains/{domain_id} | domains.domain.write |
DELETE /domains/{domain_id} | domains.domain.delete |
POST /domains/{domain_id}/refresh | domains.domain.write |
GET /domains/tld-prices | domains.tld_price.read |
POST /domains/tld-prices | domains.tld_price.manage |
DELETE /domains/tld-prices/{price_id} | domains.tld_price.manage |
POST /domains/tld-prices/price-increase | domains.tld_price.manage |
POST /domains/tld-prices/price-increase/preview | domains.tld_price.manage |
Parameters and schemas per endpoint
GET /api/v1/domains
Section titled “GET /api/v1/domains”List Domains
Permission: domains.domain.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
company_id | string | |
q | string | |
sort | string | name | company | status | registrar | dns | dnssec | email_enabled | start_date | next_invoice_date | created_at | updated_at, ’-’ desc |
invoiceable | boolean | Filter on the resolved billing answer (#298), not the stored flag: false lists what is registered elsewhere and therefore never invoiced. |
status | string | active | redirect | parked | expired | inactive |
registrar_provider_id | string | |
dns_provider_id | string | |
count | boolean | Compute total; set false for name-only lookups (default true) |
meta | boolean | Resolve the display fields a picker discards — client/provider names, party labels, the register facts and the resolved price. False leaves them at their empty values. (default true) |
Returns: 200 · Page_DomainRead_
POST /api/v1/domains
Section titled “POST /api/v1/domains”Create Domain
Permission: domains.domain.write
Request body: DomainCreate
Returns: 201 · DomainRead
GET /api/v1/domains/{domain_id}
Section titled “GET /api/v1/domains/{domain_id}”Get Domain
Permission: domains.domain.read
Path parameters: domain_id
Returns: 200 · DomainRead
PATCH /api/v1/domains/{domain_id}
Section titled “PATCH /api/v1/domains/{domain_id}”Update Domain
Permission: domains.domain.write
Path parameters: domain_id
Request body: DomainUpdate
Returns: 200 · DomainRead
DELETE /api/v1/domains/{domain_id}
Section titled “DELETE /api/v1/domains/{domain_id}”Delete Domain
Permission: domains.domain.delete
Path parameters: domain_id
Returns: 204
POST /api/v1/domains/{domain_id}/refresh
Section titled “POST /api/v1/domains/{domain_id}/refresh”Refresh Domain Dns — Re-query public DNS for this domain’s nameservers + DNSSEC now (#92).
Permission: domains.domain.write
Path parameters: domain_id
Returns: 200 · DomainRead
GET /api/v1/domains/tld-prices
Section titled “GET /api/v1/domains/tld-prices”List Tld Prices — The per-TLD price list: current, scheduled and past rows, plus unpriced TLDs.
Permission: domains.tld_price.read
Returns: 200 · TldPriceGroup[]
POST /api/v1/domains/tld-prices
Section titled “POST /api/v1/domains/tld-prices”Set Tld Price — Append a price row for a TLD (a same-day row is corrected in place).
Permission: domains.tld_price.manage
Request body: TldPriceUpsert
Returns: 200 · TldPriceRow
DELETE /api/v1/domains/tld-prices/{price_id}
Section titled “DELETE /api/v1/domains/tld-prices/{price_id}”Delete Tld Price — Remove one history row (undo a scheduled increase or a mistake).
Permission: domains.tld_price.manage
Path parameters: price_id
Returns: 204
POST /api/v1/domains/tld-prices/price-increase
Section titled “POST /api/v1/domains/tld-prices/price-increase”Apply Tld Price Increase — Apply a price change: one history row per TLD, effective valid_from.
Permission: domains.tld_price.manage
Request body: TldPriceIncreaseRequest
Returns: 200 · TldPriceIncreaseResult
POST /api/v1/domains/tld-prices/price-increase/preview
Section titled “POST /api/v1/domains/tld-prices/price-increase/preview”Preview Tld Price Increase — What a price change would do — nothing is written (#231’s preview-then-apply).
Permission: domains.tld_price.manage
Request body: TldPriceIncreaseRequest
Returns: 200 · TldPriceIncreaseResult
websites
Section titled “websites”| Endpoint | Permission |
|---|---|
GET /websites | websites.website.read |
POST /websites | websites.website.write |
GET /websites/{website_id} | websites.website.read |
PATCH /websites/{website_id} | websites.website.write |
DELETE /websites/{website_id} | websites.website.delete |
GET /websites/available-domains | websites.website.write |
Parameters and schemas per endpoint
GET /api/v1/websites
Section titled “GET /api/v1/websites”List Websites
Permission: websites.website.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
domain_id | string | |
company_id | string | |
q | string | Matches the parent domain’s name |
hosting_id | string | |
uptime_enabled | boolean | |
sort | string | name | company | hosting | uptime | created_at | updated_at, ’-’ desc |
count | boolean | Compute total; set false for name-only lookups (default true) |
meta | boolean | Resolve the display fields a picker discards — the parent domain’s name and client, the hosting account’s name and the technical owner’s label. (default true) |
Returns: 200 · Page_WebsiteRead_
POST /api/v1/websites
Section titled “POST /api/v1/websites”Create Website
Permission: websites.website.write
Request body: WebsiteCreate
Returns: 201 · WebsiteRead
GET /api/v1/websites/{website_id}
Section titled “GET /api/v1/websites/{website_id}”Get Website
Permission: websites.website.read
Path parameters: website_id
Returns: 200 · WebsiteRead
PATCH /api/v1/websites/{website_id}
Section titled “PATCH /api/v1/websites/{website_id}”Update Website
Permission: websites.website.write
Path parameters: website_id
Request body: WebsiteUpdate
Returns: 200 · WebsiteRead
DELETE /api/v1/websites/{website_id}
Section titled “DELETE /api/v1/websites/{website_id}”Delete Website
Permission: websites.website.delete
Path parameters: website_id
Returns: 204
GET /api/v1/websites/available-domains
Section titled “GET /api/v1/websites/available-domains”List Available Domains — The domains that do not have a website yet — the create picker’s options.
Permission: websites.website.write
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 200) |
Returns: 200 · AvailableDomain[]
hosting
Section titled “hosting”| Endpoint | Permission |
|---|---|
GET /hosting | hosting.hosting.read |
POST /hosting | hosting.hosting.write |
GET /hosting/{hosting_id} | hosting.hosting.read |
PATCH /hosting/{hosting_id} | hosting.hosting.write |
DELETE /hosting/{hosting_id} | hosting.hosting.delete |
Parameters and schemas per endpoint
GET /api/v1/hosting
Section titled “GET /api/v1/hosting”List Hosting
Permission: hosting.hosting.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
company_id | string | |
q | string | |
sort | string | name | ip_address | created_at | updated_at, ’-’ desc |
count | boolean | Compute total; set false for name-only lookups (default true) |
meta | boolean | Resolve the display fields a picker discards — the client’s and provider’s names and the contact’s label. (default true) |
Returns: 200 · Page_HostingRead_
POST /api/v1/hosting
Section titled “POST /api/v1/hosting”Create Hosting
Permission: hosting.hosting.write
Request body: HostingCreate
Returns: 201 · HostingRead
GET /api/v1/hosting/{hosting_id}
Section titled “GET /api/v1/hosting/{hosting_id}”Get Hosting
Permission: hosting.hosting.read
Path parameters: hosting_id
Returns: 200 · HostingRead
PATCH /api/v1/hosting/{hosting_id}
Section titled “PATCH /api/v1/hosting/{hosting_id}”Update Hosting
Permission: hosting.hosting.write
Path parameters: hosting_id
Request body: HostingUpdate
Returns: 200 · HostingRead
DELETE /api/v1/hosting/{hosting_id}
Section titled “DELETE /api/v1/hosting/{hosting_id}”Delete Hosting
Permission: hosting.hosting.delete
Path parameters: hosting_id
Returns: 204
cloudflare
Section titled “cloudflare”| Endpoint | Permission |
|---|---|
GET /cloudflare/accounts | cloudflare.settings.manage |
POST /cloudflare/accounts | cloudflare.settings.manage |
PATCH /cloudflare/accounts/{account_id} | cloudflare.settings.manage |
DELETE /cloudflare/accounts/{account_id} | cloudflare.settings.manage |
POST /cloudflare/accounts/{account_id}/sync | cloudflare.settings.manage |
POST /cloudflare/accounts/{account_id}/verify | cloudflare.settings.manage |
GET /cloudflare/accounts/options | cloudflare.dns.read |
POST /cloudflare/domains/{domain_id}/check | cloudflare.dns.read |
POST /cloudflare/domains/{domain_id}/connect | cloudflare.zone.manage |
POST /cloudflare/domains/{domain_id}/pages | cloudflare.zone.manage |
PUT /cloudflare/domains/{domain_id}/redirect | cloudflare.zone.manage |
DELETE /cloudflare/domains/{domain_id}/redirect | cloudflare.zone.manage |
POST /cloudflare/domains/{domain_id}/redirect/adopt | cloudflare.zone.manage |
PUT /cloudflare/domains/{domain_id}/redirect/rules/{rule_id} | cloudflare.zone.manage |
DELETE /cloudflare/domains/{domain_id}/redirect/rules/{rule_id} | cloudflare.zone.manage |
GET /cloudflare/domains/{domain_id}/status | cloudflare.dns.read |
DELETE /cloudflare/pages/links/{link_id} | cloudflare.zone.manage |
GET /cloudflare/pages/projects | cloudflare.dns.read |
GET /cloudflare/zones | cloudflare.dns.read |
GET /cloudflare/zones/{zone_id}/dns | cloudflare.dns.read |
POST /cloudflare/zones/{zone_id}/dns | cloudflare.zone.manage |
PATCH /cloudflare/zones/{zone_id}/dns/{record_id} | cloudflare.zone.manage |
DELETE /cloudflare/zones/{zone_id}/dns/{record_id} | cloudflare.zone.manage |
GET /cloudflare/zones/{zone_id}/dns/export | cloudflare.dns.read |
POST /cloudflare/zones/{zone_id}/link | cloudflare.zone.manage |
DELETE /cloudflare/zones/{zone_id}/link | cloudflare.zone.manage |
Parameters and schemas per endpoint
GET /api/v1/cloudflare/accounts
Section titled “GET /api/v1/cloudflare/accounts”List Accounts — Configured Cloudflare accounts. The API token is never part of the response.
Permission: cloudflare.settings.manage
Returns: 200 · AccountRead[]
POST /api/v1/cloudflare/accounts
Section titled “POST /api/v1/cloudflare/accounts”Create Account
Permission: cloudflare.settings.manage
Request body: AccountCreate
Returns: 201 · AccountRead
PATCH /api/v1/cloudflare/accounts/{account_id}
Section titled “PATCH /api/v1/cloudflare/accounts/{account_id}”Update Account — Rename, repoint or rotate. An omitted api_token keeps the stored one.
Permission: cloudflare.settings.manage
Path parameters: account_id
Request body: AccountUpdate
Returns: 200 · AccountRead
DELETE /api/v1/cloudflare/accounts/{account_id}
Section titled “DELETE /api/v1/cloudflare/accounts/{account_id}”Delete Account — Forget the credential and its synced inventory. Nothing at Cloudflare is deleted.
Permission: cloudflare.settings.manage
Path parameters: account_id
Returns: 204
POST /api/v1/cloudflare/accounts/{account_id}/sync
Section titled “POST /api/v1/cloudflare/accounts/{account_id}/sync”Sync Account — Pull the account’s zones and Pages projects, matching zones to domains by apex.
Permission: cloudflare.settings.manage
Path parameters: account_id
Returns: 200 · AccountSyncResult
POST /api/v1/cloudflare/accounts/{account_id}/verify
Section titled “POST /api/v1/cloudflare/accounts/{account_id}/verify”Verify Account — Probe what this token can do and store the answer, so the UI can name a missing scope.
Permission: cloudflare.settings.manage
Path parameters: account_id
Returns: 200 · AccountVerifyResult
GET /api/v1/cloudflare/accounts/options
Section titled “GET /api/v1/cloudflare/accounts/options”List Account Options — Names only, for the “which account” picker — choosing one is zone.manage’s job, and should not require holding the credential screen’s permission.
Permission: cloudflare.dns.read
Returns: 200 · AccountOption[]
POST /api/v1/cloudflare/domains/{domain_id}/check
Section titled “POST /api/v1/cloudflare/domains/{domain_id}/check”Cloudflare Check Domain — Ask Cloudflare what it actually has: drift, conflicting redirects, whether the apex is proxied at all. Persists the observation; every probe fails softly and names itself.
Permission: cloudflare.dns.read
Path parameters: domain_id
Returns: 200 · DomainStatusRead
POST /api/v1/cloudflare/domains/{domain_id}/connect
Section titled “POST /api/v1/cloudflare/domains/{domain_id}/connect”Connect Domain — Adopt this domain’s existing Cloudflare zone, or create one. Adoption always wins.
Permission: cloudflare.zone.manage
Path parameters: domain_id
Request body: ConnectRequest
Returns: 200 · ZoneRead
POST /api/v1/cloudflare/domains/{domain_id}/pages
Section titled “POST /api/v1/cloudflare/domains/{domain_id}/pages”Link Pages Project — Serve a hostname of this domain from a Pages project (registers it and points DNS).
Permission: cloudflare.zone.manage
Path parameters: domain_id
Request body: PagesLinkCreate
Returns: 201 · PagesLinkRead
PUT /api/v1/cloudflare/domains/{domain_id}/redirect
Section titled “PUT /api/v1/cloudflare/domains/{domain_id}/redirect”Set Redirect — Set the domain-wide redirect and push it to Cloudflare as a Redirect Rule.
Permission: cloudflare.zone.manage
Path parameters: domain_id
Request body: RedirectWrite
Returns: 200 · RedirectRead
DELETE /api/v1/cloudflare/domains/{domain_id}/redirect
Section titled “DELETE /api/v1/cloudflare/domains/{domain_id}/redirect”Remove Redirect — Delete the rule we created at Cloudflare. Rules we did not create are never touched.
Permission: cloudflare.zone.manage
Path parameters: domain_id
Returns: 204
POST /api/v1/cloudflare/domains/{domain_id}/redirect/adopt
Section titled “POST /api/v1/cloudflare/domains/{domain_id}/redirect/adopt”Adopt Redirect — Take ownership of a Redirect Rule the zone already has. Writes nothing at Cloudflare.
Permission: cloudflare.zone.manage
Path parameters: domain_id
Request body: RedirectAdopt
Returns: 200 · RedirectRead
PUT /api/v1/cloudflare/domains/{domain_id}/redirect/rules/{rule_id}
Section titled “PUT /api/v1/cloudflare/domains/{domain_id}/redirect/rules/{rule_id}”Edit Zone Redirect — Change where an existing Redirect Rule sends traffic. Never changes what it matches.
Permission: cloudflare.zone.manage
Path parameters: domain_id, rule_id
Request body: RedirectRuleEdit
Returns: 200 · DomainStatusRead
DELETE /api/v1/cloudflare/domains/{domain_id}/redirect/rules/{rule_id}
Section titled “DELETE /api/v1/cloudflare/domains/{domain_id}/redirect/rules/{rule_id}”Delete Zone Redirect — Delete one Redirect Rule from this zone by id, resolved inside the zone’s own ruleset.
Permission: cloudflare.zone.manage
Path parameters: domain_id, rule_id
Returns: 200 · DomainStatusRead
GET /api/v1/cloudflare/domains/{domain_id}/status
Section titled “GET /api/v1/cloudflare/domains/{domain_id}/status”Cloudflare Domain Status — Stored state only — no Cloudflare call, so this is safe on a page load.
Permission: cloudflare.dns.read
Path parameters: domain_id
Returns: 200 · DomainStatusRead
DELETE /api/v1/cloudflare/pages/links/{link_id}
Section titled “DELETE /api/v1/cloudflare/pages/links/{link_id}”Unlink Pages Project — Detach the hostname from the project. Its DNS record is left alone on purpose.
Permission: cloudflare.zone.manage
Path parameters: link_id
Returns: 204
GET /api/v1/cloudflare/pages/projects
Section titled “GET /api/v1/cloudflare/pages/projects”List Pages Projects — Synced Pages projects — the picker’s source, so it never waits on Cloudflare.
Permission: cloudflare.dns.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
account_id | string |
Returns: 200 · PagesProjectRead[]
GET /api/v1/cloudflare/zones
Section titled “GET /api/v1/cloudflare/zones”List Zones
Permission: cloudflare.dns.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
account_id | string | |
domain_id | string | |
linked | boolean | true: matched to a domain; false: orphans |
q | string | |
count | boolean | Compute the total. False for pickers. (default true) |
Returns: 200 · Page_ZoneRead_
GET /api/v1/cloudflare/zones/{zone_id}/dns
Section titled “GET /api/v1/cloudflare/zones/{zone_id}/dns”List Dns — The zone’s records, read live from Cloudflare — never a cached copy (see schemas).
Permission: cloudflare.dns.read
Path parameters: zone_id
Returns: 200 · ZoneRecords
POST /api/v1/cloudflare/zones/{zone_id}/dns
Section titled “POST /api/v1/cloudflare/zones/{zone_id}/dns”Create Dns Record
Permission: cloudflare.zone.manage
Path parameters: zone_id
Request body: DnsRecordWrite
Returns: 201 · DnsRecordRead
PATCH /api/v1/cloudflare/zones/{zone_id}/dns/{record_id}
Section titled “PATCH /api/v1/cloudflare/zones/{zone_id}/dns/{record_id}”Update Dns Record
Permission: cloudflare.zone.manage
Path parameters: zone_id, record_id
Request body: DnsRecordWrite
Returns: 200 · DnsRecordRead
DELETE /api/v1/cloudflare/zones/{zone_id}/dns/{record_id}
Section titled “DELETE /api/v1/cloudflare/zones/{zone_id}/dns/{record_id}”Delete Dns Record
Permission: cloudflare.zone.manage
Path parameters: zone_id, record_id
Returns: 204
GET /api/v1/cloudflare/zones/{zone_id}/dns/export
Section titled “GET /api/v1/cloudflare/zones/{zone_id}/dns/export”Export Dns — The zone as a BIND file (Cloudflare’s own export) or a CSV built here.
Permission: cloudflare.dns.read
Path parameters: zone_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
format | string | (default bind) |
Returns: 200 · DnsExport
POST /api/v1/cloudflare/zones/{zone_id}/link
Section titled “POST /api/v1/cloudflare/zones/{zone_id}/link”Link Zone — Match a synced zone to a domain by hand, where the apex did not match automatically.
Permission: cloudflare.zone.manage
Path parameters: zone_id
Request body: ZoneLink
Returns: 200 · ZoneRead
DELETE /api/v1/cloudflare/zones/{zone_id}/link
Section titled “DELETE /api/v1/cloudflare/zones/{zone_id}/link”Unlink Zone — Forget the match. The zone keeps serving at Cloudflare.
Permission: cloudflare.zone.manage
Path parameters: zone_id
Returns: 200 · ZoneRead
| Endpoint | Permission |
|---|---|
GET /oxxa/accounts | oxxa.settings.manage |
POST /oxxa/accounts | oxxa.settings.manage |
PATCH /oxxa/accounts/{account_id} | oxxa.settings.manage |
DELETE /oxxa/accounts/{account_id} | oxxa.settings.manage |
POST /oxxa/accounts/{account_id}/sync | oxxa.registrar.sync |
POST /oxxa/accounts/{account_id}/verify | oxxa.settings.manage |
GET /oxxa/accounts/options | oxxa.registrar.sync |
GET /oxxa/domains | oxxa.registrar.sync |
POST /oxxa/domains/{domain_id}/nameservers | oxxa.registrar.manage |
POST /oxxa/domains/{domain_id}/refresh | oxxa.registrar.sync |
GET /oxxa/domains/{domain_id}/status | oxxa.registrar.sync |
Parameters and schemas per endpoint
GET /api/v1/oxxa/accounts
Section titled “GET /api/v1/oxxa/accounts”List Accounts — Configured OXXA logins. The API password is never part of the response.
Permission: oxxa.settings.manage
Returns: 200 · OxxaAccountRead[]
POST /api/v1/oxxa/accounts
Section titled “POST /api/v1/oxxa/accounts”Create Account — Store a credential. Creating does not verify it — /verify is the explicit probe, so a typo is reported on the settings screen rather than as a failed save.
Permission: oxxa.settings.manage
Request body: OxxaAccountCreate
Returns: 201 · OxxaAccountRead
PATCH /api/v1/oxxa/accounts/{account_id}
Section titled “PATCH /api/v1/oxxa/accounts/{account_id}”Update Account — Rename, repoint or rotate. An omitted api_password keeps the stored one.
Permission: oxxa.settings.manage
Path parameters: account_id
Request body: OxxaAccountUpdate
Returns: 200 · OxxaAccountRead
DELETE /api/v1/oxxa/accounts/{account_id}
Section titled “DELETE /api/v1/oxxa/accounts/{account_id}”Delete Account — Forget the credential and the register synced from it. Nothing at OXXA is deleted.
Permission: oxxa.settings.manage
Path parameters: account_id
Returns: 204
POST /api/v1/oxxa/accounts/{account_id}/sync
Section titled “POST /api/v1/oxxa/accounts/{account_id}/sync”Sync Account — Pull the whole register and reconcile it. One request to OXXA, not one per domain.
Permission: oxxa.registrar.sync
Path parameters: account_id
Returns: 200 · OxxaAccountSyncResult
POST /api/v1/oxxa/accounts/{account_id}/verify
Section titled “POST /api/v1/oxxa/accounts/{account_id}/verify”Verify Account — Probe the credential and cache the TLDs it may operate on.
Permission: oxxa.settings.manage
Path parameters: account_id
Returns: 200 · OxxaAccountVerifyResult
GET /api/v1/oxxa/accounts/options
Section titled “GET /api/v1/oxxa/accounts/options”List Account Options — Names only, for the “which register” picker — choosing one is the sync/push caller’s job, and should not require holding the credential screen’s permission.
Permission: oxxa.registrar.sync
Returns: 200 · OxxaAccountOption[]
GET /api/v1/oxxa/domains
Section titled “GET /api/v1/oxxa/domains”List Register — The stored register. linked=false is the one worth looking at: domains the agency is paying to renew that no schakl record — and therefore no invoice — knows about.
Permission: oxxa.registrar.sync
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
account_id | string | |
linked | boolean | true = matched to a schakl domain, false = only the unmatched |
q | string | |
count | boolean | false skips the count query (docs/PERFORMANCE.md) (default true) |
Returns: 200 · Page_RegistrarDomainRead_
POST /api/v1/oxxa/domains/{domain_id}/nameservers
Section titled “POST /api/v1/oxxa/domains/{domain_id}/nameservers”Push Nameservers — Repoint the domain’s delegation at the registrar.
Permission: oxxa.registrar.manage
Path parameters: domain_id
Request body: NameserverPush
Returns: 200 · NameserverPushResult
POST /api/v1/oxxa/domains/{domain_id}/refresh
Section titled “POST /api/v1/oxxa/domains/{domain_id}/refresh”Refresh Domain — Re-read one domain from the registrar, including DNSSEC and the registrant’s name.
Permission: oxxa.registrar.sync
Path parameters: domain_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
account_id | string |
Returns: 200 · DomainRegistrarStatus
GET /api/v1/oxxa/domains/{domain_id}/status
Section titled “GET /api/v1/oxxa/domains/{domain_id}/status”Domain Status — Stored rows only — never calls OXXA, so the domain page renders when OXXA is down.
Permission: oxxa.registrar.sync
Path parameters: domain_id
Returns: 200 · DomainRegistrarStatus
uptime
Section titled “uptime”| Endpoint | Permission |
|---|---|
POST /uptime/hook/{token} | Deliberately open |
GET /uptime/instances | uptime.instance.manage |
POST /uptime/instances | uptime.instance.manage |
GET /uptime/instances/{instance_id} | uptime.instance.manage |
PATCH /uptime/instances/{instance_id} | uptime.instance.manage |
DELETE /uptime/instances/{instance_id} | uptime.instance.manage |
POST /uptime/instances/{instance_id}/enrol | uptime.instance.manage |
POST /uptime/instances/{instance_id}/links/apply | uptime.monitor.write |
POST /uptime/instances/{instance_id}/probe | uptime.instance.manage |
POST /uptime/instances/{instance_id}/sync | uptime.instance.manage |
GET /uptime/instances/selectable | uptime.monitor.read |
GET /uptime/monitors | uptime.monitor.read |
POST /uptime/monitors | uptime.monitor.write |
GET /uptime/monitors/{monitor_id} | uptime.monitor.read |
PATCH /uptime/monitors/{monitor_id} | uptime.monitor.write |
DELETE /uptime/monitors/{monitor_id} | uptime.monitor.write |
POST /uptime/monitors/{monitor_id}/link | uptime.monitor.write |
POST /uptime/monitors/{monitor_id}/pause | uptime.monitor.pause |
POST /uptime/monitors/{monitor_id}/reconcile | uptime.monitor.write |
POST /uptime/monitors/{monitor_id}/resume | uptime.monitor.pause |
GET /uptime/profiles | uptime.monitor.read |
POST /uptime/profiles | uptime.profile.manage |
PATCH /uptime/profiles/{profile_id} | uptime.profile.manage |
DELETE /uptime/profiles/{profile_id} | uptime.profile.manage |
Parameters and schemas per endpoint
POST /api/v1/uptime/hook/{token}
Section titled “POST /api/v1/uptime/hook/{token}”Uptime Hook — Ingest one reported heartbeat.
Permission: Deliberately open
Path parameters: token
Returns: 200
GET /api/v1/uptime/instances
Section titled “GET /api/v1/uptime/instances”List Instances
Permission: uptime.instance.manage
Returns: 200 · UptimeInstanceRead[]
POST /api/v1/uptime/instances
Section titled “POST /api/v1/uptime/instances”Create Instance
Permission: uptime.instance.manage
Request body: UptimeInstanceCreate
Returns: 201 · UptimeInstanceRead
GET /api/v1/uptime/instances/{instance_id}
Section titled “GET /api/v1/uptime/instances/{instance_id}”Get Instance
Permission: uptime.instance.manage
Path parameters: instance_id
Returns: 200 · UptimeInstanceRead
PATCH /api/v1/uptime/instances/{instance_id}
Section titled “PATCH /api/v1/uptime/instances/{instance_id}”Update Instance
Permission: uptime.instance.manage
Path parameters: instance_id
Request body: UptimeInstanceUpdate
Returns: 200 · UptimeInstanceRead
DELETE /api/v1/uptime/instances/{instance_id}
Section titled “DELETE /api/v1/uptime/instances/{instance_id}”Delete Instance
Permission: uptime.instance.manage
Path parameters: instance_id
Returns: 204
POST /api/v1/uptime/instances/{instance_id}/enrol
Section titled “POST /api/v1/uptime/instances/{instance_id}/enrol”Enrol Instance — Authenticate once and store the token. The password never reaches the database.
Permission: uptime.instance.manage
Path parameters: instance_id
Request body: UptimeEnrol
Returns: 200 · UptimeProbeResult
POST /api/v1/uptime/instances/{instance_id}/links/apply
Section titled “POST /api/v1/uptime/instances/{instance_id}/links/apply”Apply Links — Confirm every unambiguous proposal on this instance; report what was left.
Permission: uptime.monitor.write
Path parameters: instance_id
Returns: 200 · UptimeLinkApplyResult
POST /api/v1/uptime/instances/{instance_id}/probe
Section titled “POST /api/v1/uptime/instances/{instance_id}/probe”Probe Instance
Permission: uptime.instance.manage
Path parameters: instance_id
Returns: 200 · UptimeProbeResult
POST /api/v1/uptime/instances/{instance_id}/sync
Section titled “POST /api/v1/uptime/instances/{instance_id}/sync”Sync Instance — Read every monitor into the mirror. Writes nothing to Uptime Kuma.
Permission: uptime.instance.manage
Path parameters: instance_id
Returns: 200 · UptimeSyncReport
GET /api/v1/uptime/instances/selectable
Section titled “GET /api/v1/uptime/instances/selectable”List Selectable Instances — Which Uptime Kumas a monitor may be created on — the create form’s picker (#366).
Permission: uptime.monitor.read
Returns: 200 · UptimeInstanceOption[]
GET /api/v1/uptime/monitors
Section titled “GET /api/v1/uptime/monitors”List Monitors
Permission: uptime.monitor.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
limit | integer | (default 50) |
offset | integer | (default 0) |
instance_id | string | |
company_id | string | |
website_id | string | |
domain_id | string | |
hosting_id | string | |
sync_status | string | |
monitor_type | string | Filter by type; ‘group’ lists the groups an instance has |
link_status | string | linked / matched / ambiguous / unmatched, ‘proposed’ for everything a sync found a candidate for and nobody has confirmed yet, or ‘unlinked’ for everything still attachable |
count | boolean | Compute total; set false for pickers (default true) |
meta | boolean | Resolve display names; skip it for pickers (default false) |
Returns: 200 · Page_UptimeMonitorRead_
POST /api/v1/uptime/monitors
Section titled “POST /api/v1/uptime/monitors”Create Monitor — Create the monitor here and push it to Uptime Kuma.
Permission: uptime.monitor.write
Request body: UptimeMonitorCreate
Returns: 201 · UptimeMonitorRead
GET /api/v1/uptime/monitors/{monitor_id}
Section titled “GET /api/v1/uptime/monitors/{monitor_id}”Get Monitor
Permission: uptime.monitor.read
Path parameters: monitor_id
Returns: 200 · UptimeMonitorRead
PATCH /api/v1/uptime/monitors/{monitor_id}
Section titled “PATCH /api/v1/uptime/monitors/{monitor_id}”Update Monitor
Permission: uptime.monitor.write
Path parameters: monitor_id
Request body: UptimeMonitorUpdate
Returns: 200 · UptimeMonitorRead
DELETE /api/v1/uptime/monitors/{monitor_id}
Section titled “DELETE /api/v1/uptime/monitors/{monitor_id}”Delete Monitor
Permission: uptime.monitor.write
Path parameters: monitor_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
at_kuma | boolean | Also delete the monitor in Uptime Kuma. Defaults to false: ‘stop tracking this here’ and ‘stop watching this client’s site’ are different decisions. (default false) |
Returns: 204
POST /api/v1/uptime/monitors/{monitor_id}/link
Section titled “POST /api/v1/uptime/monitors/{monitor_id}/link”Link Monitor — Attach a found monitor to the website, domain or hosting it watches (#321).
Permission: uptime.monitor.write
Path parameters: monitor_id
Request body: UptimeMonitorLink
Returns: 200 · UptimeMonitorRead
POST /api/v1/uptime/monitors/{monitor_id}/pause
Section titled “POST /api/v1/uptime/monitors/{monitor_id}/pause”Pause Monitor — Its own permission: silencing an alert during a planned migration is an ordinary act, and repointing a monitor is not.
Permission: uptime.monitor.pause
Path parameters: monitor_id
Returns: 200 · UptimeMonitorRead
POST /api/v1/uptime/monitors/{monitor_id}/reconcile
Section titled “POST /api/v1/uptime/monitors/{monitor_id}/reconcile”Reconcile Monitor — Resolve a drift in the direction the caller names. There is no default direction: one overwrites a colleague’s edit in Uptime Kuma, the other overwrites schakl’s record.
Permission: uptime.monitor.write
Path parameters: monitor_id
Request body: UptimeReconcile
Returns: 200 · UptimeMonitorRead
POST /api/v1/uptime/monitors/{monitor_id}/resume
Section titled “POST /api/v1/uptime/monitors/{monitor_id}/resume”Resume Monitor
Permission: uptime.monitor.pause
Path parameters: monitor_id
Returns: 200 · UptimeMonitorRead
GET /api/v1/uptime/profiles
Section titled “GET /api/v1/uptime/profiles”List Profiles — Readable on monitor.read, writable on profile.manage.
Permission: uptime.monitor.read
Returns: 200 · UptimeProfileRead[]
POST /api/v1/uptime/profiles
Section titled “POST /api/v1/uptime/profiles”Create Profile
Permission: uptime.profile.manage
Request body: UptimeProfileCreate
Returns: 201 · UptimeProfileRead
PATCH /api/v1/uptime/profiles/{profile_id}
Section titled “PATCH /api/v1/uptime/profiles/{profile_id}”Update Profile
Permission: uptime.profile.manage
Path parameters: profile_id
Request body: UptimeProfileUpdate
Returns: 200 · UptimeProfileRead
DELETE /api/v1/uptime/profiles/{profile_id}
Section titled “DELETE /api/v1/uptime/profiles/{profile_id}”Delete Profile
Permission: uptime.profile.manage
Path parameters: profile_id
Returns: 204
wordpress
Section titled “wordpress”| Endpoint | Permission |
|---|---|
GET /wordpress/sites | wordpress.site.read |
POST /wordpress/sites | wordpress.site.manage |
GET /wordpress/sites/{site_id} | wordpress.site.read |
PATCH /wordpress/sites/{site_id} | wordpress.site.manage |
DELETE /wordpress/sites/{site_id} | wordpress.site.manage |
GET /wordpress/sites/{site_id}/brands | wordpress.site.read |
POST /wordpress/sites/{site_id}/verify | wordpress.site.manage |
GET /wordpress/sites/by-website/{website_id} | wordpress.site.read |
Parameters and schemas per endpoint
GET /api/v1/wordpress/sites
Section titled “GET /api/v1/wordpress/sites”List Sites
Permission: wordpress.site.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
website_id | string |
Returns: 200 · WordPressSiteRead[]
POST /api/v1/wordpress/sites
Section titled “POST /api/v1/wordpress/sites”Connect Site
Permission: wordpress.site.manage
Request body: WordPressSiteCreate
Returns: 201 · WordPressSiteRead
GET /api/v1/wordpress/sites/{site_id}
Section titled “GET /api/v1/wordpress/sites/{site_id}”Get Site
Permission: wordpress.site.read
Path parameters: site_id
Returns: 200 · WordPressSiteRead
PATCH /api/v1/wordpress/sites/{site_id}
Section titled “PATCH /api/v1/wordpress/sites/{site_id}”Update Site
Permission: wordpress.site.manage
Path parameters: site_id
Request body: WordPressSiteUpdate
Returns: 200 · WordPressSiteRead
DELETE /api/v1/wordpress/sites/{site_id}
Section titled “DELETE /api/v1/wordpress/sites/{site_id}”Disconnect Site
Permission: wordpress.site.manage
Path parameters: site_id
Returns: 204
GET /api/v1/wordpress/sites/{site_id}/brands
Section titled “GET /api/v1/wordpress/sites/{site_id}/brands”List Brands — The Rank Math brands this site tracks — the marketing link picker’s options.
Permission: wordpress.site.read
Path parameters: site_id
Returns: 200 · WordPressBrand[]
POST /api/v1/wordpress/sites/{site_id}/verify
Section titled “POST /api/v1/wordpress/sites/{site_id}/verify”Verify Site — Probe the site and store what was observed.
Permission: wordpress.site.manage
Path parameters: site_id
Returns: 200 · WordPressVerifyResult
GET /api/v1/wordpress/sites/by-website/{website_id}
Section titled “GET /api/v1/wordpress/sites/by-website/{website_id}”Site For Website — The one credential a website has, or null.
Permission: wordpress.site.read
Path parameters: website_id
Returns: 200 · WordPressSiteRead