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.
128 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 |
GET /domains/totals | domains.domain.read |
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
GET /api/v1/domains/totals
Section titled “GET /api/v1/domains/totals”Domain Totals — What the filtered register adds up to, per client and as a whole.
Permission: domains.domain.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
company_id | string | |
q | string | |
invoiceable | boolean | The list’s own filter: the resolved billing answer (#298). |
status | string | |
registrar_provider_id | string | |
dns_provider_id | string |
Returns: 200 · DomainTotalsReport
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}/abilities | wordpress.ability.read |
POST /wordpress/sites/{site_id}/abilities/run | wordpress.ability.read |
GET /wordpress/sites/{site_id}/brands | wordpress.site.read |
GET /wordpress/sites/{site_id}/bridge | wordpress.site.read |
GET /wordpress/sites/{site_id}/bridge/languages | wordpress.content.read |
POST /wordpress/sites/{site_id}/bridge/media | wordpress.content.write |
GET /wordpress/sites/{site_id}/bridge/menus | wordpress.content.read |
GET /wordpress/sites/{site_id}/bridge/menus/{menu} | wordpress.content.read |
POST /wordpress/sites/{site_id}/bridge/menus/{menu}/items | wordpress.content.publish |
DELETE /wordpress/sites/{site_id}/bridge/menus/{menu}/items/{item_id} | wordpress.content.publish |
GET /wordpress/sites/{site_id}/bridge/options | wordpress.content.read |
GET /wordpress/sites/{site_id}/bridge/options/{page} | wordpress.content.read |
PATCH /wordpress/sites/{site_id}/bridge/options/{page} | wordpress.content.publish |
GET /wordpress/sites/{site_id}/bridge/records | wordpress.content.read |
POST /wordpress/sites/{site_id}/bridge/records | wordpress.content.write |
GET /wordpress/sites/{site_id}/bridge/records/{wp_id} | wordpress.content.read |
PATCH /wordpress/sites/{site_id}/bridge/records/{wp_id} | wordpress.content.write |
DELETE /wordpress/sites/{site_id}/bridge/records/{wp_id} | wordpress.content.delete |
GET /wordpress/sites/{site_id}/bridge/records/{wp_id}/translations | wordpress.content.read |
POST /wordpress/sites/{site_id}/bridge/records/{wp_id}/translations | wordpress.content.write |
GET /wordpress/sites/{site_id}/bridge/schema | wordpress.content.read |
GET /wordpress/sites/{site_id}/bridge/strings | wordpress.content.read |
PUT /wordpress/sites/{site_id}/bridge/strings | wordpress.content.publish |
GET /wordpress/sites/{site_id}/bridge/terms | wordpress.content.read |
POST /wordpress/sites/{site_id}/bridge/terms | wordpress.content.write |
GET /wordpress/sites/{site_id}/content | wordpress.content.read |
POST /wordpress/sites/{site_id}/content | wordpress.content.write |
GET /wordpress/sites/{site_id}/content/{type}/{wp_id} | wordpress.content.read |
PATCH /wordpress/sites/{site_id}/content/{type}/{wp_id} | wordpress.content.write |
GET /wordpress/sites/{site_id}/forms | wordpress.forms.read |
POST /wordpress/sites/{site_id}/forms | wordpress.forms.write |
GET /wordpress/sites/{site_id}/forms/{wp_id} | wordpress.forms.read |
PATCH /wordpress/sites/{site_id}/forms/{wp_id} | wordpress.forms.write |
GET /wordpress/sites/{site_id}/media | wordpress.content.read |
GET /wordpress/sites/{site_id}/media/{wp_id} | wordpress.content.read |
POST /wordpress/sites/{site_id}/rest | wordpress.rest.read |
GET /wordpress/sites/{site_id}/summary | 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 — Every connected site, or a website’s, or a client’s — the question an agent asks first, since a client is how it was told about the site.
Permission: wordpress.site.read
Query parameters:
| Name | Type | Meaning |
|---|---|---|
website_id | string | |
company_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}/abilities
Section titled “GET /api/v1/wordpress/sites/{site_id}/abilities”List Site Abilities — Every ability the site registers for REST, with its input schema and whether it is read-only — what run may be asked for.
Permission: wordpress.ability.read
Path parameters: site_id
Returns: 200 · WordPressAbility[]
POST /api/v1/wordpress/sites/{site_id}/abilities/run
Section titled “POST /api/v1/wordpress/sites/{site_id}/abilities/run”Run Site Ability — Run one ability by name. A read-only ability runs on wordpress.ability.read; any other needs wordpress.ability.run — decided by the ability’s own annotation.
Permission: wordpress.ability.read
Path parameters: site_id
Request body: WordPressAbilityRun
Returns: 200 · WordPressAbilityResult
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[]
GET /api/v1/wordpress/sites/{site_id}/bridge
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge”Bridge Info — What the site is, through the schakl WordPress MCP Bridge plugin: versions, every post type (including ones hidden from the REST API), taxonomies, ACF options pages, menus, WPML languages, the SEO plugin, and what the stored credential may do. The read to make first on a site that has the plugin; 409 names the plugin on one that does not.
Permission: wordpress.site.read
Path parameters: site_id
Returns: 200 · WordPressBridgeInfo
GET /api/v1/wordpress/sites/{site_id}/bridge/languages
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/languages”Bridge Languages — WPML: the active languages and the default; 409 on a site without WPML.
Permission: wordpress.content.read
Path parameters: site_id
Returns: 200 · WordPressLanguages
POST /api/v1/wordpress/sites/{site_id}/bridge/media
Section titled “POST /api/v1/wordpress/sites/{site_id}/bridge/media”Bridge Upload Media — Upload a file to the site’s media library from a URL or a base64 body, with alt text. Returns the attachment; use its id in image fields or as featured_media.
Permission: wordpress.content.write
Path parameters: site_id
Request body: WordPressMediaUpload
Returns: 201 · WordPressBridgeMedia
GET /api/v1/wordpress/sites/{site_id}/bridge/menus
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/menus”Bridge Menus — The navigation menus and the theme locations they fill.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
lang | string |
Returns: 200 · WordPressMenuList
GET /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}”Bridge Menu — One menu as a tree of items.
Permission: wordpress.content.read
Path parameters: site_id, menu
Returns: 200 · WordPressMenu
POST /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}/items
Section titled “POST /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}/items”Bridge Menu Add Item — Add a record, a term or a custom link to a menu — live at once, hence publish.
Permission: wordpress.content.publish
Path parameters: site_id, menu
Request body: WordPressMenuItemAdd
Returns: 201 · WordPressMenu
DELETE /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}/items/{item_id}
Section titled “DELETE /api/v1/wordpress/sites/{site_id}/bridge/menus/{menu}/items/{item_id}”Bridge Menu Remove Item — Remove one item from a menu.
Permission: wordpress.content.publish
Path parameters: site_id, menu, item_id
Returns: 200 · WordPressMenu
GET /api/v1/wordpress/sites/{site_id}/bridge/options
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/options”Bridge Options Pages — The site’s ACF options pages (company details, footer, partners …).
Permission: wordpress.content.read
Path parameters: site_id
Returns: 200 · WordPressOptionsPages
GET /api/v1/wordpress/sites/{site_id}/bridge/options/{page}
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/options/{page}”Bridge Options Get — The values on one options page, compact, with references; per language under WPML.
Permission: wordpress.content.read
Path parameters: site_id, page
Query parameters:
| Name | Type | Meaning |
|---|---|---|
lang | string | |
mode | string | (default compact) |
include_schema | boolean | (default false) |
Returns: 200 · WordPressOptionsRead
PATCH /api/v1/wordpress/sites/{site_id}/bridge/options/{page}
Section titled “PATCH /api/v1/wordpress/sites/{site_id}/bridge/options/{page}”Bridge Options Update — Write ACF values on an options page. Live at once and site-wide, hence publish.
Permission: wordpress.content.publish
Path parameters: site_id, page
Request body: WordPressOptionsWrite
Returns: 200 · WordPressOptionsRead
GET /api/v1/wordpress/sites/{site_id}/bridge/records
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/records”Bridge List Records — Records of any post type through the plugin — REST-hidden types included — with the page path, status, and WPML language and translation ids per row.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
post_type | string | (default page) |
search | string | |
status | string | Comma-separated, or ‘any’. |
lang | string | |
parent | integer | |
page | integer | (default 1) |
per_page | integer | (default 20) |
Returns: 200 · WordPressRecordList
POST /api/v1/wordpress/sites/{site_id}/bridge/records
Section titled “POST /api/v1/wordpress/sites/{site_id}/bridge/records”Bridge Create Record — A new record with its ACF fields, validated against the site’s schema before anything is written; a refusal lists every problem with its path in details.problems. A live status needs wordpress.content.publish.
Permission: wordpress.content.write
Path parameters: site_id
Request body: WordPressRecordCreate
Returns: 201 · WordPressRecord
GET /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}”Bridge Get Record — One record whole: core fields, taxonomies, SEO, the ACF fields (compact: per page-builder row only what that row uses) and references for every id in them.
Permission: wordpress.content.read
Path parameters: site_id, wp_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
mode | string | (default compact) |
include_schema | boolean | (default false) |
Returns: 200 · WordPressRecord
PATCH /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}
Section titled “PATCH /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}”Bridge Update Record — Change a record: fields replaces named top-level ACF fields whole, ops edits one row by path without resending the rest. Validated first; nothing written on a refusal. Editing anything a visitor can see needs wordpress.content.publish.
Permission: wordpress.content.write
Path parameters: site_id, wp_id
Request body: WordPressRecordUpdate
Returns: 200 · WordPressRecord
DELETE /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}
Section titled “DELETE /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}”Bridge Delete Record — Trash a record (recoverable in the site’s admin), or delete it for good.
Permission: wordpress.content.delete
Path parameters: site_id, wp_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
force | boolean | Delete permanently instead of trashing. (default false) |
Returns: 200 · WordPressBridgeDelete
GET /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}/translations
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}/translations”Bridge Translations — WPML: a record’s translation group — per language the id, title, status and whether it is the original.
Permission: wordpress.content.read
Path parameters: site_id, wp_id
Returns: 200 · WordPressTranslations
POST /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}/translations
Section titled “POST /api/v1/wordpress/sites/{site_id}/bridge/records/{wp_id}/translations”Bridge Translate — WPML: create this record’s translation in lang, linked to it — the source copied with its references translated, your title/content/fields applied on top — or, with translation_id, connect an existing record as the translation. A live status needs wordpress.content.publish.
Permission: wordpress.content.write
Path parameters: site_id, wp_id
Request body: WordPressTranslationCreate
Returns: 201 · WordPressRecord
GET /api/v1/wordpress/sites/{site_id}/bridge/schema
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/schema”Bridge Schema — The ACF field schema for a post type (optionally with template/parent), a record, an options page or a taxonomy: every field’s name, type, choices, sub fields, the conditions that hide it, and the JSON the writer takes. Read before writing fields.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
post_type | string | |
template | string | |
parent | integer | |
wp_id | integer | An existing record: the groups that apply to it. |
options_page | string | |
taxonomy | string |
Returns: 200 · WordPressBridgeSchema
GET /api/v1/wordpress/sites/{site_id}/bridge/strings
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/strings”Bridge Strings — WPML String Translation: the registered strings with their translations per language.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
domain | string | |
search | string | |
page | integer | (default 1) |
per_page | integer | (default 50) |
Returns: 200 · WordPressStringList
PUT /api/v1/wordpress/sites/{site_id}/bridge/strings
Section titled “PUT /api/v1/wordpress/sites/{site_id}/bridge/strings”Bridge String Update — WPML String Translation: set a string’s translation — live at once, hence publish.
Permission: wordpress.content.publish
Path parameters: site_id
Request body: WordPressStringUpdate
Returns: 200 · WordPressStringResult
GET /api/v1/wordpress/sites/{site_id}/bridge/terms
Section titled “GET /api/v1/wordpress/sites/{site_id}/bridge/terms”Bridge List Terms — The terms of one taxonomy, with their WPML language and, on request, ACF fields.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
taxonomy | string · required | |
search | string | |
lang | string | |
mode | string | (default none) |
Returns: 200 · WordPressBridgeTermList
POST /api/v1/wordpress/sites/{site_id}/bridge/terms
Section titled “POST /api/v1/wordpress/sites/{site_id}/bridge/terms”Bridge Create Term — A new term, its ACF fields validated first; with WPML, in a language and optionally as the translation of another term.
Permission: wordpress.content.write
Path parameters: site_id
Request body: WordPressBridgeTermCreate
Returns: 201 · WordPressBridgeTerm
GET /api/v1/wordpress/sites/{site_id}/content
Section titled “GET /api/v1/wordpress/sites/{site_id}/content”List Site Content — Pages, posts or any custom post type, drafts included, newest change first.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
type | string | (default page) |
search | string | |
status | string | |
lang | string | |
page | integer | (default 1) |
per_page | integer | (default 20) |
Returns: 200 · WordPressContentList
POST /api/v1/wordpress/sites/{site_id}/content
Section titled “POST /api/v1/wordpress/sites/{site_id}/content”Create Site Content — A new page or post — a draft unless status says otherwise, and a live status needs wordpress.content.publish.
Permission: wordpress.content.write
Path parameters: site_id
Request body: WordPressContentCreate
Returns: 201 · WordPressContentRead
GET /api/v1/wordpress/sites/{site_id}/content/{type}/{wp_id}
Section titled “GET /api/v1/wordpress/sites/{site_id}/content/{type}/{wp_id}”Get Site Content — One record whole: raw content, rendered HTML, the ACF fields, the meta.
Permission: wordpress.content.read
Path parameters: site_id, type, wp_id
Returns: 200 · WordPressContentRead
PATCH /api/v1/wordpress/sites/{site_id}/content/{type}/{wp_id}
Section titled “PATCH /api/v1/wordpress/sites/{site_id}/content/{type}/{wp_id}”Update Site Content — Change a record. Absent fields are left alone. Editing anything a visitor can see, or setting a live status, needs wordpress.content.publish.
Permission: wordpress.content.write
Path parameters: site_id, type, wp_id
Request body: WordPressContentWrite
Returns: 200 · WordPressContentRead
GET /api/v1/wordpress/sites/{site_id}/forms
Section titled “GET /api/v1/wordpress/sites/{site_id}/forms”List Site Forms — The site’s Contact Form 7 forms.
Permission: wordpress.forms.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
search | string |
Returns: 200 · WordPressFormRow[]
POST /api/v1/wordpress/sites/{site_id}/forms
Section titled “POST /api/v1/wordpress/sites/{site_id}/forms”Create Site Form
Permission: wordpress.forms.write
Path parameters: site_id
Request body: WordPressFormCreate
Returns: 201 · WordPressFormRead
GET /api/v1/wordpress/sites/{site_id}/forms/{wp_id}
Section titled “GET /api/v1/wordpress/sites/{site_id}/forms/{wp_id}”Get Site Form — One form whole: template, field names, both mails, messages, extra settings.
Permission: wordpress.forms.read
Path parameters: site_id, wp_id
Returns: 200 · WordPressFormRead
PATCH /api/v1/wordpress/sites/{site_id}/forms/{wp_id}
Section titled “PATCH /api/v1/wordpress/sites/{site_id}/forms/{wp_id}”Update Site Form — Change a form. Live the moment it saves; absent fields are left alone.
Permission: wordpress.forms.write
Path parameters: site_id, wp_id
Request body: WordPressFormWrite
Returns: 200 · WordPressFormRead
GET /api/v1/wordpress/sites/{site_id}/media
Section titled “GET /api/v1/wordpress/sites/{site_id}/media”List Site Media — The media library — what an ACF image id resolves to.
Permission: wordpress.content.read
Path parameters: site_id
Query parameters:
| Name | Type | Meaning |
|---|---|---|
search | string | |
page | integer | (default 1) |
per_page | integer | (default 20) |
Returns: 200 · WordPressMediaList
GET /api/v1/wordpress/sites/{site_id}/media/{wp_id}
Section titled “GET /api/v1/wordpress/sites/{site_id}/media/{wp_id}”Get Site Media
Permission: wordpress.content.read
Path parameters: site_id, wp_id
Returns: 200 · WordPressMediaRow
POST /api/v1/wordpress/sites/{site_id}/rest
Section titled “POST /api/v1/wordpress/sites/{site_id}/rest”Call Site Rest — Any call to the site’s REST API, under the stored credential — the escape hatch for a plugin namespace no curated route above knows (read them off summary.namespaces).
Permission: wordpress.rest.read
Path parameters: site_id
Request body: WordPressRestCall
Returns: 200 · WordPressRestResult
GET /api/v1/wordpress/sites/{site_id}/summary
Section titled “GET /api/v1/wordpress/sites/{site_id}/summary”Site Summary — What the site is: name, WordPress and PHP version, post types, plugin namespaces.
Permission: wordpress.site.read
Path parameters: site_id
Returns: 200 · WordPressSiteSummary
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