Skip to content

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.

EndpointPermission
GET /domainsdomains.domain.read
POST /domainsdomains.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}/refreshdomains.domain.write
GET /domains/tld-pricesdomains.tld_price.read
POST /domains/tld-pricesdomains.tld_price.manage
DELETE /domains/tld-prices/{price_id}domains.tld_price.manage
POST /domains/tld-prices/price-increasedomains.tld_price.manage
POST /domains/tld-prices/price-increase/previewdomains.tld_price.manage
Parameters and schemas per endpoint

List Domains

Permission: domains.domain.read

Query parameters:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
company_idstring
qstring
sortstringname | company | status | registrar | dns | dnssec | email_enabled | start_date | next_invoice_date | created_at | updated_at, ’-’ desc
invoiceablebooleanFilter on the resolved billing answer (#298), not the stored flag: false lists what is registered elsewhere and therefore never invoiced.
statusstringactive | redirect | parked | expired | inactive
registrar_provider_idstring
dns_provider_idstring
countbooleanCompute total; set false for name-only lookups (default true)
metabooleanResolve 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_

Create Domain

Permission: domains.domain.write

Request body: DomainCreate

Returns: 201 · DomainRead

Get Domain

Permission: domains.domain.read

Path parameters: domain_id

Returns: 200 · DomainRead

Update Domain

Permission: domains.domain.write

Path parameters: domain_id

Request body: DomainUpdate

Returns: 200 · DomainRead

Delete Domain

Permission: domains.domain.delete

Path parameters: domain_id

Returns: 204

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

List Tld Prices — The per-TLD price list: current, scheduled and past rows, plus unpriced TLDs.

Permission: domains.tld_price.read

Returns: 200 · TldPriceGroup[]

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

EndpointPermission
GET /websiteswebsites.website.read
POST /websiteswebsites.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-domainswebsites.website.write
Parameters and schemas per endpoint

List Websites

Permission: websites.website.read

Query parameters:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
domain_idstring
company_idstring
qstringMatches the parent domain’s name
hosting_idstring
uptime_enabledboolean
sortstringname | company | hosting | uptime | created_at | updated_at, ’-’ desc
countbooleanCompute total; set false for name-only lookups (default true)
metabooleanResolve 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_

Create Website

Permission: websites.website.write

Request body: WebsiteCreate

Returns: 201 · WebsiteRead

Get Website

Permission: websites.website.read

Path parameters: website_id

Returns: 200 · WebsiteRead

Update Website

Permission: websites.website.write

Path parameters: website_id

Request body: WebsiteUpdate

Returns: 200 · WebsiteRead

Delete Website

Permission: websites.website.delete

Path parameters: website_id

Returns: 204

List Available Domains — The domains that do not have a website yet — the create picker’s options.

Permission: websites.website.write

Query parameters:

NameTypeMeaning
limitinteger(default 200)

Returns: 200 · AvailableDomain[]

EndpointPermission
GET /hostinghosting.hosting.read
POST /hostinghosting.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

List Hosting

Permission: hosting.hosting.read

Query parameters:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
company_idstring
qstring
sortstringname | ip_address | created_at | updated_at, ’-’ desc
countbooleanCompute total; set false for name-only lookups (default true)
metabooleanResolve the display fields a picker discards — the client’s and provider’s names and the contact’s label. (default true)

Returns: 200 · Page_HostingRead_

Create Hosting

Permission: hosting.hosting.write

Request body: HostingCreate

Returns: 201 · HostingRead

Get Hosting

Permission: hosting.hosting.read

Path parameters: hosting_id

Returns: 200 · HostingRead

Update Hosting

Permission: hosting.hosting.write

Path parameters: hosting_id

Request body: HostingUpdate

Returns: 200 · HostingRead

Delete Hosting

Permission: hosting.hosting.delete

Path parameters: hosting_id

Returns: 204

EndpointPermission
GET /cloudflare/accountscloudflare.settings.manage
POST /cloudflare/accountscloudflare.settings.manage
PATCH /cloudflare/accounts/{account_id}cloudflare.settings.manage
DELETE /cloudflare/accounts/{account_id}cloudflare.settings.manage
POST /cloudflare/accounts/{account_id}/synccloudflare.settings.manage
POST /cloudflare/accounts/{account_id}/verifycloudflare.settings.manage
GET /cloudflare/accounts/optionscloudflare.dns.read
POST /cloudflare/domains/{domain_id}/checkcloudflare.dns.read
POST /cloudflare/domains/{domain_id}/connectcloudflare.zone.manage
POST /cloudflare/domains/{domain_id}/pagescloudflare.zone.manage
PUT /cloudflare/domains/{domain_id}/redirectcloudflare.zone.manage
DELETE /cloudflare/domains/{domain_id}/redirectcloudflare.zone.manage
POST /cloudflare/domains/{domain_id}/redirect/adoptcloudflare.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}/statuscloudflare.dns.read
DELETE /cloudflare/pages/links/{link_id}cloudflare.zone.manage
GET /cloudflare/pages/projectscloudflare.dns.read
GET /cloudflare/zonescloudflare.dns.read
GET /cloudflare/zones/{zone_id}/dnscloudflare.dns.read
POST /cloudflare/zones/{zone_id}/dnscloudflare.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/exportcloudflare.dns.read
POST /cloudflare/zones/{zone_id}/linkcloudflare.zone.manage
DELETE /cloudflare/zones/{zone_id}/linkcloudflare.zone.manage
Parameters and schemas per endpoint

List Accounts — Configured Cloudflare accounts. The API token is never part of the response.

Permission: cloudflare.settings.manage

Returns: 200 · AccountRead[]

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

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

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

List Pages Projects — Synced Pages projects — the picker’s source, so it never waits on Cloudflare.

Permission: cloudflare.dns.read

Query parameters:

NameTypeMeaning
account_idstring

Returns: 200 · PagesProjectRead[]

List Zones

Permission: cloudflare.dns.read

Query parameters:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
account_idstring
domain_idstring
linkedbooleantrue: matched to a domain; false: orphans
qstring
countbooleanCompute 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:

NameTypeMeaning
formatstring(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

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

EndpointPermission
GET /oxxa/accountsoxxa.settings.manage
POST /oxxa/accountsoxxa.settings.manage
PATCH /oxxa/accounts/{account_id}oxxa.settings.manage
DELETE /oxxa/accounts/{account_id}oxxa.settings.manage
POST /oxxa/accounts/{account_id}/syncoxxa.registrar.sync
POST /oxxa/accounts/{account_id}/verifyoxxa.settings.manage
GET /oxxa/accounts/optionsoxxa.registrar.sync
GET /oxxa/domainsoxxa.registrar.sync
POST /oxxa/domains/{domain_id}/nameserversoxxa.registrar.manage
POST /oxxa/domains/{domain_id}/refreshoxxa.registrar.sync
GET /oxxa/domains/{domain_id}/statusoxxa.registrar.sync
Parameters and schemas per endpoint

List Accounts — Configured OXXA logins. The API password is never part of the response.

Permission: oxxa.settings.manage

Returns: 200 · OxxaAccountRead[]

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

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 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

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[]

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:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
account_idstring
linkedbooleantrue = matched to a schakl domain, false = only the unmatched
qstring
countbooleanfalse 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:

NameTypeMeaning
account_idstring

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

EndpointPermission
POST /uptime/hook/{token}Deliberately open
GET /uptime/instancesuptime.instance.manage
POST /uptime/instancesuptime.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}/enroluptime.instance.manage
POST /uptime/instances/{instance_id}/links/applyuptime.monitor.write
POST /uptime/instances/{instance_id}/probeuptime.instance.manage
POST /uptime/instances/{instance_id}/syncuptime.instance.manage
GET /uptime/instances/selectableuptime.monitor.read
GET /uptime/monitorsuptime.monitor.read
POST /uptime/monitorsuptime.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}/linkuptime.monitor.write
POST /uptime/monitors/{monitor_id}/pauseuptime.monitor.pause
POST /uptime/monitors/{monitor_id}/reconcileuptime.monitor.write
POST /uptime/monitors/{monitor_id}/resumeuptime.monitor.pause
GET /uptime/profilesuptime.monitor.read
POST /uptime/profilesuptime.profile.manage
PATCH /uptime/profiles/{profile_id}uptime.profile.manage
DELETE /uptime/profiles/{profile_id}uptime.profile.manage
Parameters and schemas per endpoint

Uptime Hook — Ingest one reported heartbeat.

Permission: Deliberately open

Path parameters: token

Returns: 200

List Instances

Permission: uptime.instance.manage

Returns: 200 · UptimeInstanceRead[]

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

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[]

List Monitors

Permission: uptime.monitor.read

Query parameters:

NameTypeMeaning
limitinteger(default 50)
offsetinteger(default 0)
instance_idstring
company_idstring
website_idstring
domain_idstring
hosting_idstring
sync_statusstring
monitor_typestringFilter by type; ‘group’ lists the groups an instance has
link_statusstringlinked / matched / ambiguous / unmatched, ‘proposed’ for everything a sync found a candidate for and nobody has confirmed yet, or ‘unlinked’ for everything still attachable
countbooleanCompute total; set false for pickers (default true)
metabooleanResolve display names; skip it for pickers (default false)

Returns: 200 · Page_UptimeMonitorRead_

Create Monitor — Create the monitor here and push it to Uptime Kuma.

Permission: uptime.monitor.write

Request body: UptimeMonitorCreate

Returns: 201 · UptimeMonitorRead

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:

NameTypeMeaning
at_kumabooleanAlso 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

List Profiles — Readable on monitor.read, writable on profile.manage.

Permission: uptime.monitor.read

Returns: 200 · UptimeProfileRead[]

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

EndpointPermission
GET /wordpress/siteswordpress.site.read
POST /wordpress/siteswordpress.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}/brandswordpress.site.read
POST /wordpress/sites/{site_id}/verifywordpress.site.manage
GET /wordpress/sites/by-website/{website_id}wordpress.site.read
Parameters and schemas per endpoint

List Sites

Permission: wordpress.site.read

Query parameters:

NameTypeMeaning
website_idstring

Returns: 200 · WordPressSiteRead[]

Connect Site

Permission: wordpress.site.manage

Request body: WordPressSiteCreate

Returns: 201 · WordPressSiteRead

Get Site

Permission: wordpress.site.read

Path parameters: site_id

Returns: 200 · WordPressSiteRead

Update Site

Permission: wordpress.site.manage

Path parameters: site_id

Request body: WordPressSiteUpdate

Returns: 200 · WordPressSiteRead

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