Developer docs/Extension reference
Cancel and modify
Everything an addon can stop or change before it happens, and exactly what it may change. There are three kinds: typed pre-events, request events on every mutating API route, and mixins.
#Rules
- Only the
beforephase can cancel or modify.during,afterandfinishedonly observe (the reply is ignored). - Listeners run in priority order. Each sees the payload as changed by the ones before it, and
input.cancelledtells it whether an earlier listener cancelled. - After a cancel, later listeners are skipped unless their hook sets
ignore_cancelled: true. Only those may replyuncancel, which clears the cancel. monitorlisteners always run last and cannot change anything; a non-continue reply is logged and ignored.- A cancel answers the API call with HTTP 409 and
error.addon_hook_cancelled. The reason (at most 200 characters) is logged, not shown to the user. - If a hook errors or times out (
timeout_ms, default 500, capped by the sandbox),fail_open: true(default) continues andfail_open: falseblocks the action with 409error.addon_hook_failed. - A
modifymust be a JSON object. The host reads back only the keys listed for the event; other keys are ignored. - Money keys (
amount,price,unit_price,total,subtotal,tax,tax_total,discount,setup_fee,recurring_amount,credit,fee,balance,amount_paid) change only for addons withcapabilities.money.modify, must be exact decimal strings (at most 4 places), and every change is audited asaddon.money_modified. Without the capability the money keys are reverted and the rest of the change is kept. - Secrets never reach addons:
password,current_password,new_password,password_confirmation,secret,client_secret,token,api_key,totp,otp,mfa_code,recovery_code,card_number,cvc,cvvand any key ending in_password,_secretor_tokenare replaced by"[redacted]"and restored afterwards, so they can be neither read nor changed.
#Reply format
The Rust SDK builds these with reply::proceed(), reply::modify(p), reply::cancel(reason) and reply::uncancel().
#Typed pre-events
| Event | Cancel | Modifiable keys and rules | Payload |
|---|---|---|---|
login.before | yes | none (read-only) | email, ip, user_agent |
client.before_register | yes | display_name: String of at most 200 bytes; anything else keeps the submitted name | email, display_name, ip |
order.before_place | yes | coupon: Non-empty string of at most 64 bytes sets the code, null removes it, any other value keeps the submitted code. The code is then validated like a typed one | customer_id, currency, items, coupon |
invoice.before_create | yes | items[].description: Non-blank string of at most 500 bytes, matched by position; otherwise the original line text; items[].unit_price: Needs capabilities.money.modify; an exact decimal string (at most 4 places), audited as addon.money_modified. Without the capability the change is reverted | customer_id, currency, finalize, items |
#Example: cancel, modify and uncancel
/// Pre-events and lifecycle phases listed in `capabilities.hooks` call op
/// `hook`. Return `proceed`, `modify(payload)` or `cancel(reason)`.
/// `order.before_place` with `ignore_cancelled: true` and priority `highest`:
/// this runs even after an earlier addon cancelled the order. `uncancel` is
/// only honoured for such hooks. Here: always allow orders using the
/// `GUIDE-VIP` coupon, and normalise coupon codes to upper case (`coupon` is
/// the only key the host reads back from this event).
#Request events (every mutating route)
Every POST, PUT, PATCH and DELETE under /api/v1 (except addon routes) is an event named <METHOD> <route template>. A hook before:<METHOD> <route> gets {method, path, route, query, body} and may cancel the request or rewrite body (the JSON request body, at most 1 MiB, money and secret rules apply). Patterns: before:* (every request), before:POST /api/v1/admin/* (prefix), or an exact template. Because they see every request, these hooks are a dangerous capability (hooks.any) the admin must approve at install. during, after (with the JSON response) and finished (with status and http_status) observe.
459 cancellable request events:
| Hook event | Action |
|---|---|
before:DELETE /api/v1/account/identities/{id} | unlink |
before:DELETE /api/v1/account/oauth-apps/{id} | my revoke |
before:DELETE /api/v1/account/privacy/erasure | |
before:POST /api/v1/account/privacy/erasure | |
before:DELETE /api/v1/account/security-question | |
before:PUT /api/v1/account/security-question | |
before:POST /api/v1/account/tos/accept | accept tos |
before:PUT /api/v1/admin/addons/registry/settings | put registry settings |
before:POST /api/v1/admin/addons/registry/{id}/install | registry install |
before:POST /api/v1/admin/addons/upload | upload |
before:DELETE /api/v1/admin/addons/{id} | uninstall |
before:POST /api/v1/admin/addons/{id}/disable | disable |
before:POST /api/v1/admin/addons/{id}/enable | enable |
before:POST /api/v1/admin/addons/{id}/install | install |
before:POST /api/v1/admin/addons/{id}/mixins | mixins toggle |
before:PUT /api/v1/admin/addons/{id}/settings | put settings |
before:POST /api/v1/admin/affiliates/materials | |
before:DELETE /api/v1/admin/affiliates/materials/{id} | |
before:PUT /api/v1/admin/affiliates/materials/{id} | |
before:POST /api/v1/admin/affiliates/payouts/{id} | |
before:PUT /api/v1/admin/affiliates/product-rates | |
before:DELETE /api/v1/admin/affiliates/product-rates/{product_id} | |
before:POST /api/v1/admin/affiliates/tiers | |
before:DELETE /api/v1/admin/affiliates/tiers/{id} | |
before:PUT /api/v1/admin/affiliates/{id} | |
before:POST /api/v1/admin/announcements | |
before:DELETE /api/v1/admin/announcements/{id} | |
before:PUT /api/v1/admin/announcements/{id} | |
before:DELETE /api/v1/admin/api-keys/{id} | |
before:POST /api/v1/admin/automation/{kind}/run | |
before:PUT /api/v1/admin/automation/{kind}/settings | put setting |
before:POST /api/v1/admin/autopay/run | Run auto-pay now (idempotent with the daily job). |
before:POST /api/v1/admin/backups | |
before:DELETE /api/v1/admin/backups/{id} | |
before:POST /api/v1/admin/banned-emails | add |
before:DELETE /api/v1/admin/banned-emails/{domain} | remove |
before:POST /api/v1/admin/billable-items | |
before:DELETE /api/v1/admin/billable-items/{id} | |
before:POST /api/v1/admin/bundles | |
before:DELETE /api/v1/admin/bundles/{id} | |
before:PUT /api/v1/admin/bundles/{id} | |
before:POST /api/v1/admin/campaigns | |
before:POST /api/v1/admin/campaigns/preview | |
before:DELETE /api/v1/admin/campaigns/{id} | |
before:PUT /api/v1/admin/campaigns/{id} | |
before:POST /api/v1/admin/campaigns/{id}/cancel | |
before:DELETE /api/v1/admin/campaigns/{id}/schedule | |
before:POST /api/v1/admin/campaigns/{id}/schedule | Hold a draft until send_at; the worker snapshots recipients then. |
before:POST /api/v1/admin/campaigns/{id}/send | |
before:POST /api/v1/admin/cancellations/{id}/decide | |
before:POST /api/v1/admin/catalog/addons | |
before:PUT /api/v1/admin/catalog/addons/{id} | |
before:POST /api/v1/admin/catalog/groups | |
before:POST /api/v1/admin/catalog/products | |
before:PATCH /api/v1/admin/catalog/products/{id} | |
before:PUT /api/v1/admin/catalog/products/{id}/billing | |
before:POST /api/v1/admin/catalog/products/{id}/fields | |
before:DELETE /api/v1/admin/catalog/products/{id}/fields/{field} | |
before:PUT /api/v1/admin/catalog/products/{id}/fields/{field} | |
before:PUT /api/v1/admin/catalog/products/{id}/fixed-term | |
before:POST /api/v1/admin/catalog/products/{id}/options | |
before:DELETE /api/v1/admin/catalog/products/{id}/options/{option} | |
before:PUT /api/v1/admin/catalog/products/{id}/prices | |
before:PUT /api/v1/admin/catalog/products/{id}/recommendations | |
before:PUT /api/v1/admin/catalog/products/{id}/stock | |
before:POST /api/v1/admin/chats/{id}/close | |
before:POST /api/v1/admin/chats/{id}/messages | |
before:POST /api/v1/admin/client-fields | |
before:DELETE /api/v1/admin/client-fields/{id} | |
before:PUT /api/v1/admin/client-fields/{id} | |
before:POST /api/v1/admin/client-group-rules | create |
before:POST /api/v1/admin/client-group-rules/apply | apply |
before:DELETE /api/v1/admin/client-group-rules/{id} | remove |
before:PUT /api/v1/admin/client-group-rules/{id} | update |
before:POST /api/v1/admin/client-groups | |
before:DELETE /api/v1/admin/client-groups/{id} | |
before:PUT /api/v1/admin/client-groups/{id} | |
before:POST /api/v1/admin/client-groups/{id}/members | |
before:DELETE /api/v1/admin/client-groups/{id}/members/{customer_id} | |
before:DELETE /api/v1/admin/contact-messages/{id} | contact del |
before:PUT /api/v1/admin/contact-messages/{id} | contact status |
before:POST /api/v1/admin/contact-messages/{id}/ticket | contact to ticket |
before:POST /api/v1/admin/coupons | |
before:DELETE /api/v1/admin/coupons/{id} | |
before:PUT /api/v1/admin/coupons/{id} | |
before:POST /api/v1/admin/currencies | |
before:PUT /api/v1/admin/currencies/rates/settings | |
before:POST /api/v1/admin/currencies/rates/update | |
before:POST /api/v1/admin/currencies/sync-prices | |
before:PUT /api/v1/admin/currencies/{code} | |
before:POST /api/v1/admin/currencies/{code}/default | |
before:PUT /api/v1/admin/custom-code | |
before:POST /api/v1/admin/customers | |
before:PATCH /api/v1/admin/customers/{id} | |
before:PUT /api/v1/admin/customers/{id}/auto-pay | |
before:POST /api/v1/admin/customers/{id}/billable-items/invoice | |
before:POST /api/v1/admin/customers/{id}/close | close customer |
before:POST /api/v1/admin/customers/{id}/credit | |
before:PUT /api/v1/admin/customers/{id}/fields | |
before:POST /api/v1/admin/customers/{id}/group | |
before:PUT /api/v1/admin/customers/{id}/kyc | |
before:PUT /api/v1/admin/customers/{id}/legal-entity | |
before:POST /api/v1/admin/customers/{id}/login-as | login as customer |
before:POST /api/v1/admin/customers/{id}/merge | merge customer |
before:POST /api/v1/admin/customers/{id}/notes | |
before:DELETE /api/v1/admin/customers/{id}/notes/{note} | |
before:PUT /api/v1/admin/customers/{id}/notes/{note} | |
before:POST /api/v1/admin/customers/{id}/security-question/verify | Check a caller's answer. Rate limited per customer and audited. |
before:POST /api/v1/admin/customers/{id}/vat/verify | |
before:POST /api/v1/admin/domains/bulk | admin bulk |
before:PUT /api/v1/admin/domains/margins | |
before:PUT /api/v1/admin/domains/premium-settings | |
before:POST /api/v1/admin/domains/run | |
before:POST /api/v1/admin/domains/sync-prices | |
before:PUT /api/v1/admin/domains/tld-fields/{tld} | |
before:PATCH /api/v1/admin/domains/{id} | |
before:PUT /api/v1/admin/domains/{id}/dns | admin dns put |
before:POST /api/v1/admin/domains/{id}/registrant-verification | |
before:POST /api/v1/admin/domains/{id}/ssl-check | |
before:POST /api/v1/admin/domains/{id}/sync | |
before:POST /api/v1/admin/downloads | |
before:DELETE /api/v1/admin/downloads/{id} | |
before:POST /api/v1/admin/email-log/{id}/resend | admin resend |
before:PUT /api/v1/admin/email-templates/{name}/enabled | Switch a template on or off; disabled templates are never queued. |
before:DELETE /api/v1/admin/email-templates/{name}/{locale} | |
before:PUT /api/v1/admin/email-templates/{name}/{locale} | |
before:POST /api/v1/admin/email-templates/{name}/{locale}/preview | |
before:POST /api/v1/admin/email-templates/{name}/{locale}/test | Queue the saved template, with sample data, to the signed-in admin. |
before:POST /api/v1/admin/emails/{job}/resend | |
before:POST /api/v1/admin/gateways/custom | |
before:DELETE /api/v1/admin/gateways/{id} | |
before:PUT /api/v1/admin/gateways/{id} | |
before:PUT /api/v1/admin/gateways/{id}/rules | |
before:POST /api/v1/admin/gateways/{id}/test-webhook | Verify + parse a pasted webhook without applying it (logged as a test). |
before:POST /api/v1/admin/gdpr/requests/{id}/approve | |
before:POST /api/v1/admin/gdpr/requests/{id}/reject | |
before:PUT /api/v1/admin/general-settings | |
before:POST /api/v1/admin/gift-cards | |
before:POST /api/v1/admin/gift-cards/{id}/disable | |
before:POST /api/v1/admin/import/csv/analyze | Headers, a 5-row preview, the target fields and a suggested mapping. |
before:POST /api/v1/admin/import/csv/run | Validate every row; unless dry_run, import them all-or-nothing. |
before:POST /api/v1/admin/inactive-clients/run | Run the erasure now with the saved settings (no-op when disabled). |
before:POST /api/v1/admin/invoices | |
before:POST /api/v1/admin/invoices/bulk | Apply one action to many invoices; returns a per-invoice result. |
before:POST /api/v1/admin/invoices/merge | |
before:POST /api/v1/admin/invoices/{id}/apply-credit | |
before:POST /api/v1/admin/invoices/{id}/credit-note | |
before:POST /api/v1/admin/invoices/{id}/debit-note | Issue a debit note (extra charge) against an unpaid or paid invoice. |
before:POST /api/v1/admin/invoices/{id}/duplicate | |
before:POST /api/v1/admin/invoices/{id}/finalize | |
before:POST /api/v1/admin/invoices/{id}/items | |
before:PUT /api/v1/admin/invoices/{id}/notes | |
before:POST /api/v1/admin/invoices/{id}/payments | Record a manual payment (bank transfer…). Idempotent. |
before:POST /api/v1/admin/invoices/{id}/split | |
before:POST /api/v1/admin/invoices/{id}/void | |
before:POST /api/v1/admin/jobs/recurring | Enqueue a recurring-billing run now (deduplicated per minute). |
before:POST /api/v1/admin/jobs/{id}/retry | |
before:POST /api/v1/admin/kb/articles | |
before:DELETE /api/v1/admin/kb/articles/{id} | |
before:PUT /api/v1/admin/kb/articles/{id} | |
before:PUT /api/v1/admin/kb/articles/{id}/tags | put tags |
before:POST /api/v1/admin/kb/categories | |
before:DELETE /api/v1/admin/kb/categories/{id} | |
before:PUT /api/v1/admin/kb/categories/{id} | |
before:POST /api/v1/admin/kyc/documents/{id}/review | |
before:PUT /api/v1/admin/kyc/settings | |
before:POST /api/v1/admin/legal-entities | |
before:DELETE /api/v1/admin/legal-entities/default | |
before:DELETE /api/v1/admin/legal-entities/{id} | |
before:PUT /api/v1/admin/legal-entities/{id} | |
before:POST /api/v1/admin/legal-entities/{id}/default | |
before:POST /api/v1/admin/mass/customers | |
before:POST /api/v1/admin/mass/domains | |
before:POST /api/v1/admin/mass/services | |
before:POST /api/v1/admin/mass/tickets | |
before:POST /api/v1/admin/module-queue/{id}/retry | |
before:PUT /api/v1/admin/my-notes | |
before:POST /api/v1/admin/network-issues | |
before:DELETE /api/v1/admin/network-issues/{id} | |
before:PUT /api/v1/admin/network-issues/{id} | |
before:POST /api/v1/admin/network-issues/{id}/updates | |
before:POST /api/v1/admin/noticeboard | |
before:DELETE /api/v1/admin/noticeboard/{id} | Authors delete their own notices; staff with settings access can delete any. |
before:POST /api/v1/admin/notification-rules | |
before:POST /api/v1/admin/notification-rules/preview | Payload that would be POSTed for an event (no network call). |
before:DELETE /api/v1/admin/notification-rules/{id} | |
before:PUT /api/v1/admin/notification-rules/{id} | |
before:DELETE /api/v1/admin/notification-rules/{id}/secret | Stop signing a webhook. |
before:POST /api/v1/admin/notification-rules/{id}/secret | Rotate the HMAC signing secret of a generic webhook; returned once. |
before:POST /api/v1/admin/notification-rules/{id}/test | Queue a test delivery through the real channel. |
before:POST /api/v1/admin/oauth-clients | admin create |
before:DELETE /api/v1/admin/oauth-clients/{id} | admin delete |
before:PATCH /api/v1/admin/oauth-clients/{id} | admin update |
before:POST /api/v1/admin/oauth-clients/{id}/secret | admin rotate |
before:POST /api/v1/admin/order-forms | admin create |
before:DELETE /api/v1/admin/order-forms/{id} | admin delete |
before:PUT /api/v1/admin/order-forms/{id} | admin update |
before:POST /api/v1/admin/orders | Manual order for a customer, priced from the catalog like a client order. |
before:POST /api/v1/admin/orders/bulk | |
before:DELETE /api/v1/admin/orders/{id} | |
before:POST /api/v1/admin/orders/{id}/approve | |
before:POST /api/v1/admin/orders/{id}/cancel | |
before:POST /api/v1/admin/orders/{id}/notes | |
before:POST /api/v1/admin/orders/{id}/pending | |
before:POST /api/v1/admin/orders/{id}/refund | Refund an order: credit the paid invoice in full (credit note) and close |
before:POST /api/v1/admin/overdue/run | Run today's overdue automation now (idempotent with the daily job). |
before:POST /api/v1/admin/payments/{id}/refunds | |
before:PUT /api/v1/admin/plugins/{id} | |
before:POST /api/v1/admin/plugins/{id}/deliveries/{did}/redeliver | |
before:PUT /api/v1/admin/plugins/{id}/settings | |
before:PUT /api/v1/admin/plugins/{id}/webhook | |
before:POST /api/v1/admin/plugins/{id}/webhook/secret | Generate a new signing secret and return it once. |
before:PUT /api/v1/admin/prefs | |
before:PUT /api/v1/admin/product-groups/{id}/order-form | admin set group |
before:PUT /api/v1/admin/products/{id}/free-domain | admin free put |
before:PUT /api/v1/admin/products/{id}/module | |
before:PUT /api/v1/admin/products/{id}/server-group | product group set |
before:POST /api/v1/admin/projects | |
before:DELETE /api/v1/admin/projects/{id} | |
before:PUT /api/v1/admin/projects/{id} | |
before:POST /api/v1/admin/projects/{id}/invoice-time | Bill all unbilled billable time on one invoice. |
before:DELETE /api/v1/admin/projects/{id}/links | |
before:POST /api/v1/admin/projects/{id}/links | |
before:POST /api/v1/admin/projects/{id}/tasks | |
before:DELETE /api/v1/admin/projects/{id}/tasks/{task} | |
before:PUT /api/v1/admin/projects/{id}/tasks/{task} | |
before:POST /api/v1/admin/projects/{id}/time | |
before:DELETE /api/v1/admin/projects/{id}/time/{entry} | |
before:POST /api/v1/admin/quotes | |
before:DELETE /api/v1/admin/quotes/{id} | |
before:PUT /api/v1/admin/quotes/{id} | |
before:POST /api/v1/admin/quotes/{id}/send | |
before:POST /api/v1/admin/roles | |
before:DELETE /api/v1/admin/roles/{id} | |
before:PUT /api/v1/admin/roles/{id} | |
before:POST /api/v1/admin/saml/idps | admin create |
before:DELETE /api/v1/admin/saml/idps/{id} | admin delete |
before:PUT /api/v1/admin/saml/idps/{id} | admin update |
before:POST /api/v1/admin/saml/idps/{id}/rotate-key | admin rotate key |
before:POST /api/v1/admin/saml/idps/{id}/validate | admin validate |
before:POST /api/v1/admin/saml/metadata | admin parse metadata |
before:POST /api/v1/admin/security-questions | |
before:DELETE /api/v1/admin/security-questions/{id} | |
before:PUT /api/v1/admin/security/captcha | put policy |
before:PUT /api/v1/admin/security/duo | |
before:POST /api/v1/admin/security/duo/test | |
before:POST /api/v1/admin/security/ip-rules | add rule |
before:DELETE /api/v1/admin/security/ip-rules/{id} | delete rule |
before:PUT /api/v1/admin/security/policy | put policy |
before:PUT /api/v1/admin/security/staff-2fa | Turning the policy on requires the actor to have 2FA (no self lock-out). |
before:POST /api/v1/admin/security/tos | publish tos |
before:PUT /api/v1/admin/security/trusted-proxies | |
before:POST /api/v1/admin/server-groups | groups create |
before:DELETE /api/v1/admin/server-groups/{id} | groups delete |
before:PUT /api/v1/admin/server-groups/{id} | groups update |
before:PUT /api/v1/admin/server-groups/{id}/servers | groups set members |
before:POST /api/v1/admin/servers | |
before:POST /api/v1/admin/servers/health/check | |
before:DELETE /api/v1/admin/servers/{id} | |
before:PUT /api/v1/admin/servers/{id} | |
before:POST /api/v1/admin/servers/{id}/import | Create services for panel accounts (no provisioning call; status ok). |
before:POST /api/v1/admin/servers/{id}/test | Check the stored credentials against the panel. Returns {ok, error?} |
before:POST /api/v1/admin/servers/{id}/vendor-catalog/sync | Pull the vendor catalog through the server's module. |
before:POST /api/v1/admin/services/{id}/action | |
before:DELETE /api/v1/admin/services/{id}/change | |
before:POST /api/v1/admin/services/{id}/change | |
before:POST /api/v1/admin/services/{id}/module | Manually (re)run a module action. Does not change the billing status. |
before:POST /api/v1/admin/services/{id}/module/custom | |
before:POST /api/v1/admin/services/{id}/renew-now | |
before:POST /api/v1/admin/services/{id}/usage | |
before:PUT /api/v1/admin/settings/add-funds | |
before:PUT /api/v1/admin/settings/autopay | |
before:PUT /api/v1/admin/settings/bank-transfer | |
before:PUT /api/v1/admin/settings/domain-defaults | |
before:PUT /api/v1/admin/settings/due-reminders | |
before:PUT /api/v1/admin/settings/einvoice | |
before:PUT /api/v1/admin/settings/fraud | |
before:PUT /api/v1/admin/settings/housekeeping | |
before:PUT /api/v1/admin/settings/inactive-clients | |
before:PUT /api/v1/admin/settings/invoice-branding | |
before:PUT /api/v1/admin/settings/on-demand-renewals | |
before:PUT /api/v1/admin/settings/order-approval | |
before:PUT /api/v1/admin/settings/overdue | |
before:PUT /api/v1/admin/settings/proforma | |
before:PUT /api/v1/admin/settings/registrant-verification | |
before:PUT /api/v1/admin/settings/reversal | |
before:PUT /api/v1/admin/settings/smtp | |
before:POST /api/v1/admin/settings/smtp/test | Send a test mail synchronously with the *saved* settings. |
before:PUT /api/v1/admin/settings/tax | |
before:PUT /api/v1/admin/settings/ticket-auto-close | auto close put |
before:PUT /api/v1/admin/setup-wizard/dismissed | |
before:PUT /api/v1/admin/site | admin put |
before:POST /api/v1/admin/site/pages | admin create |
before:DELETE /api/v1/admin/site/pages/{id} | admin delete |
before:PUT /api/v1/admin/site/pages/{id} | admin update |
before:PUT /api/v1/admin/support/departments/{id} | update department |
before:POST /api/v1/admin/support/departments/{id}/pipe | pipe now |
before:POST /api/v1/admin/support/spam-rules | add spam |
before:DELETE /api/v1/admin/support/spam-rules/{id} | del spam |
before:PUT /api/v1/admin/system/updates | |
before:POST /api/v1/admin/system/updates/check | |
before:POST /api/v1/admin/tax-rules | |
before:DELETE /api/v1/admin/tax-rules/{id} | |
before:PUT /api/v1/admin/tax-rules/{id} | |
before:PUT /api/v1/admin/themes/active | |
before:POST /api/v1/admin/ticket-canned | |
before:DELETE /api/v1/admin/ticket-canned/{id} | |
before:PUT /api/v1/admin/ticket-canned/{id} | |
before:POST /api/v1/admin/ticket-departments | |
before:PUT /api/v1/admin/ticket-departments/{id} | |
before:PUT /api/v1/admin/ticket-departments/{id}/sla | |
before:POST /api/v1/admin/ticket-escalations | |
before:POST /api/v1/admin/ticket-escalations/run | Enqueue an escalation pass now (durable job; the worker also schedules one |
before:DELETE /api/v1/admin/ticket-escalations/{id} | |
before:PUT /api/v1/admin/ticket-escalations/{id} | |
before:POST /api/v1/admin/ticket-statuses | |
before:DELETE /api/v1/admin/ticket-statuses/{slug} | |
before:PUT /api/v1/admin/ticket-statuses/{slug} | |
before:POST /api/v1/admin/tickets | |
before:PATCH /api/v1/admin/tickets/{id} | |
before:POST /api/v1/admin/tickets/{id}/merge | |
before:DELETE /api/v1/admin/tickets/{id}/messages/{mid} | |
before:PUT /api/v1/admin/tickets/{id}/messages/{mid} | |
before:POST /api/v1/admin/tickets/{id}/reply | |
before:POST /api/v1/admin/tickets/{id}/split | |
before:PUT /api/v1/admin/tickets/{id}/tags | |
before:POST /api/v1/admin/tickets/{id}/time | time add |
before:DELETE /api/v1/admin/tickets/{id}/time/{entry} | time del |
before:PUT /api/v1/admin/tickets/{id}/watchers | put watchers |
before:PUT /api/v1/admin/tlds | |
before:POST /api/v1/admin/tlds/bulk-adjust | admin tld adjust |
before:POST /api/v1/admin/tlds/copy-currency | admin tld copy |
before:DELETE /api/v1/admin/tlds/{tld}/{currency} | |
before:POST /api/v1/admin/todos | |
before:DELETE /api/v1/admin/todos/{id} | |
before:PUT /api/v1/admin/todos/{id} | |
before:POST /api/v1/admin/tracked-links | |
before:DELETE /api/v1/admin/tracked-links/{id} | |
before:PATCH /api/v1/admin/transactions/{id} | |
before:DELETE /api/v1/admin/translations | |
before:PUT /api/v1/admin/translations | |
before:POST /api/v1/admin/usage-metrics | |
before:DELETE /api/v1/admin/usage-metrics/{id} | |
before:PUT /api/v1/admin/usage-metrics/{id} | |
before:POST /api/v1/admin/usage/bill | |
before:POST /api/v1/admin/usage/sample | |
before:POST /api/v1/admin/users/{id}/api-keys/revoke-all | |
before:POST /api/v1/admin/users/{id}/login-as | login as user |
before:DELETE /api/v1/admin/users/{id}/passkeys | Revoke every passkey of a user (lost device / compromised account). |
before:PUT /api/v1/admin/users/{id}/roles | |
before:POST /api/v1/admin/users/{id}/verify-email | Mark a user's email address as confirmed (staff override). Idempotent. |
before:POST /api/v1/admin/vendor-catalog/{id}/import | |
before:PUT /api/v1/admin/vendor-catalog/{id}/markup | |
before:POST /api/v1/affiliates/track | SPA landing (/r/:code): validates the code and sets the tracking cookie. |
before:POST /api/v1/api-keys | |
before:DELETE /api/v1/api-keys/{id} | |
before:DELETE /api/v1/auth/avatar | |
before:PUT /api/v1/auth/avatar | |
before:POST /api/v1/auth/duo/finish | |
before:POST /api/v1/auth/duo/start | Swap the password-step challenge for a Duo authorize URL. Health-checks |
before:POST /api/v1/auth/email/resend | |
before:POST /api/v1/auth/email/verify | |
before:POST /api/v1/auth/impersonation/stop | stop impersonation |
before:PUT /api/v1/auth/locale | |
before:POST /api/v1/auth/login | |
before:POST /api/v1/auth/logout | |
before:POST /api/v1/auth/mfa/backup-codes | Replace all backup codes; returned once. |
before:POST /api/v1/auth/mfa/disable | Turn 2FA off; needs the password and a current code (or a backup code). |
before:POST /api/v1/auth/mfa/enable | |
before:POST /api/v1/auth/mfa/setup | Start enrolment: a fresh pending secret, replaced on each call until enabled. |
before:POST /api/v1/auth/mfa/verify | Second login step. Max 5 attempts per challenge, 5 minute lifetime. |
before:POST /api/v1/auth/passkeys/discover/finish | |
before:POST /api/v1/auth/passkeys/discover/start | Usernameless sign-in: empty allowCredentials, the authenticator picks a |
before:POST /api/v1/auth/passkeys/login/finish | Passwordless sign-in. A user-verified passkey counts as both factors. |
before:POST /api/v1/auth/passkeys/login/start | |
before:POST /api/v1/auth/passkeys/reauth/finish | Step-up with a passkey instead of password + code. |
before:POST /api/v1/auth/passkeys/reauth/start | |
before:POST /api/v1/auth/passkeys/register/finish | |
before:POST /api/v1/auth/passkeys/register/start | Enrolment needs the password (and 2FA code when enabled) again. |
before:DELETE /api/v1/auth/passkeys/{id} | |
before:POST /api/v1/auth/password/change | change password |
before:POST /api/v1/auth/password/forgot | |
before:POST /api/v1/auth/password/reset | |
before:POST /api/v1/auth/reauth | reauth |
before:POST /api/v1/auth/register | |
before:POST /api/v1/auth/saml/logout | logout |
before:DELETE /api/v1/auth/sessions | Sign out every other device; the calling session stays valid. |
before:DELETE /api/v1/auth/sessions/{id} | |
before:POST /api/v1/chat/sessions | |
before:POST /api/v1/chat/sessions/{id}/close | |
before:POST /api/v1/chat/sessions/{id}/messages | |
before:POST /api/v1/client/affiliate | |
before:POST /api/v1/client/affiliate/payouts | |
before:PUT /api/v1/client/billing/auto-pay | |
before:POST /api/v1/client/billing/payment-methods | |
before:DELETE /api/v1/client/billing/payment-methods/{id} | |
before:POST /api/v1/client/billing/payment-methods/{id}/default | |
before:POST /api/v1/client/checkout | Turn a cart into an order + invoice for the signed-in customer. The |
before:POST /api/v1/client/contacts | |
before:DELETE /api/v1/client/contacts/{id} | |
before:POST /api/v1/client/coupons/check | Validate a code for the order form. Returns only what the customer needs. |
before:POST /api/v1/client/credit/add-funds | Create a deposit invoice; once paid (any gateway) the amount is credited. |
before:POST /api/v1/client/domains | |
before:POST /api/v1/client/domains/bulk | client bulk |
before:PUT /api/v1/client/domains/{id}/addons | client addons |
before:PUT /api/v1/client/domains/{id}/auto-renew | |
before:PUT /api/v1/client/domains/{id}/contact | |
before:PUT /api/v1/client/domains/{id}/dns | client dns put |
before:POST /api/v1/client/domains/{id}/epp | Reveal the transfer-out (EPP) code. Audited; owner only, active domains. |
before:PUT /api/v1/client/domains/{id}/nameservers | |
before:POST /api/v1/client/domains/{id}/registrant-verification/resend | |
before:POST /api/v1/client/domains/{id}/renew | |
before:PUT /api/v1/client/email-preferences | |
before:PUT /api/v1/client/fields | |
before:POST /api/v1/client/gift-cards/redeem | |
before:POST /api/v1/client/invoices/mass-pay | Pay several of my unpaid invoices from account credit, oldest due first. |
before:POST /api/v1/client/invoices/merge | Client-side merge (WHMCS "mass payment"): combine own unpaid invoices into |
before:POST /api/v1/client/invoices/{id}/apply-credit | |
before:POST /api/v1/client/invoices/{id}/pay | Start paying an invoice with a gateway: redirect (Stripe) or manual |
before:POST /api/v1/client/kyc/documents | Raw body upload. PNG/JPEG/WebP/PDF only. |
before:DELETE /api/v1/client/kyc/documents/{id} | |
before:PUT /api/v1/client/marketing | |
before:POST /api/v1/client/orders | |
before:POST /api/v1/client/payments/{id}/complete | Payer returned from the provider: capture/check and apply (idempotent). |
before:PUT /api/v1/client/profile | |
before:POST /api/v1/client/quotes/{id}/accept | |
before:POST /api/v1/client/quotes/{id}/decline | |
before:DELETE /api/v1/client/services/{id}/cancellation | |
before:POST /api/v1/client/services/{id}/cancellation | |
before:DELETE /api/v1/client/services/{id}/change | |
before:POST /api/v1/client/services/{id}/change | |
before:POST /api/v1/client/services/{id}/module/{action} | |
before:POST /api/v1/client/services/{id}/renew-now | |
before:POST /api/v1/client/services/{id}/sso | |
before:POST /api/v1/client/subaccounts | Create a sub-account that signs in with its own email and password and |
before:POST /api/v1/client/subaccounts/invite | Invite a contact by email: the account is created with an unusable random |
before:DELETE /api/v1/client/subaccounts/{id} | Remove a contact: its access ends immediately (sessions revoked) and |
before:PUT /api/v1/client/subaccounts/{id} | |
before:POST /api/v1/client/tickets | |
before:POST /api/v1/client/tickets/{id}/close | |
before:POST /api/v1/client/tickets/{id}/rate | |
before:POST /api/v1/client/tickets/{id}/reply | |
before:POST /api/v1/client/vat/verify | |
before:POST /api/v1/compat/whmcs | handle |
before:POST /api/v1/headless/carts | Create a server-side cart owned by the key's customer; the response holds |
before:PUT /api/v1/headless/carts/{id} | |
before:POST /api/v1/headless/carts/{id}/checkout | Turn the cart into an order and a finalized invoice (fraud screening, |
before:POST /api/v1/headless/invoices/{id}/pay | Start a payment for an invoice; returns the gateway redirect/action. |
before:POST /api/v1/licensing/verify | Public. Bind on first use, then verify; the response is HMAC-signed with |
before:POST /api/v1/oauth/authorize | authorize decide |
before:POST /api/v1/public/contact | contact submit |
before:POST /api/v1/public/domains/verify-registrant | E-mail link target: confirms the registrant address (all its pending domains). |
before:POST /api/v1/public/kb/articles/{slug}/vote | |
before:POST /api/v1/sso/consume | Called by the panel. 200 with the claims the first time; 401 otherwise. |
before:POST /api/v1/sso/saml/{id}/acs | acs |
before:PUT /api/v1/store/carts/{id} | Create or replace a cart. The id is an unguessable client-generated |
before:POST /api/v1/tickets/attachments | Upload a file (raw body). Returns an id to pass as attachment_ids when |
before:POST /api/v1/unsubscribe/{token} | No CSRF/session: the unguessable token is the credential. |
before:POST /api/v1/webhooks/{gateway} |
#Mixins
A mixin wraps one core route under /api/v1 (any method, GET too; not /api/v1/auth/* or addon routes): before rewrites the request body, after rewrites the JSON response (only values of keys it already has), around does both with shared state, and return replaces the response with one of the same shape. Mixins need admin approval (mixins, mixins.return) and can be switched off per addon. See Hooks and mixins.
/// Mixins wrap a core route (`capabilities.mixins`). An `after` mixin may
/// change values of keys the response already has; new keys are dropped.