Brands tools
MCP tools for Brands: brands_create, brands_domains_add, brands_domains_list, brands_domains_remove, brands_domains_verify, brands_get, brands_go_live, brands_go_live_checklist, brands_list, brands_update.
brands_create: Create a brandbrands_domains_add: Add a custom domain to a brandbrands_domains_list: List a brand's custom domainsbrands_domains_remove: Remove a custom domain from a brandbrands_domains_verify: Check a custom domain againbrands_get: Get a brandbrands_go_live: Take a brand livebrands_go_live_checklist: Get a brand's go-live checklistbrands_list: List brandsbrands_update: Update a brand
brands_create
Create a brand. Operation brands.create · Organization level · permission brands:write · risk tier write · since M1
Creates a brand (a storefront or product line) under one of the organization's legal entities. The brand
starts in test mode only (status: test_only); it goes live through the go-live checklist.
slugis unique across Ownrecord: it appears in checkout URLs and API keys.invoiceSeries.invoice(andcreditNote, default{invoice}-CN) must be unused by every other brand of the same entity: each brand numbers its invoices in its own series within the entity.statementDescriptordefaults to the name in capitals.
The plan limits the number of brands (brands.max). Needs brands:write: organization owners and admins,
or an org or entity API key with that scope (a test-mode key creates the brand like any other key: brands
aren't mode-separated).
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
entityId | ID (ent_…) | yes | – |
name | string | yes | (1–120 characters) |
slug | string | yes | (3–40 characters) |
invoiceSeries | object | yes | – |
statementDescriptor | string | no | (5–22 characters) |
branding | object | no | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is missing or malformed (details.issues).slug_invalid: The slug has the wrong format or is a reserved word.slug_taken: Another brand already uses this slug (brand slugs are unique on Ownrecord).invoice_series_taken: Another brand of the entity already uses the invoice or credit-note series.resource_not_found: The entity doesn't exist or is outside the request's scope.scope_mismatch: The request is scoped to one brand; brands are created at an entity.entitlement_required: The plan'sbrands.maxis reached.permission_denied: You can't create brands here.
Examples
A brand with its own invoice series
Arguments:
{
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"name": "Acme App",
"slug": "acme-app",
"invoiceSeries": {
"invoice": "ACM"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
With support and legal links
Arguments:
{
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"name": "Acme App",
"slug": "acme-app",
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"statementDescriptor": "ACME APP",
"branding": {
"supportEmail": "help@acme.example",
"termsUrl": "https://acme.example/terms",
"privacyUrl": "https://acme.example/privacy"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": "help@acme.example",
"supportUrl": null,
"termsUrl": "https://acme.example/terms",
"privacyUrl": "https://acme.example/privacy"
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
brands_domains_add
Add a custom domain to a brand. Operation brands.domains.add · Organization level · permission brands:write · risk tier write · since M9
Adds a custom domain on which the brand's hosted checkout (purpose: checkout) or customer portal
(purpose: portal) is served, and attaches it to Ownrecord's hosting. The answer has the DNS records to create
at your DNS provider:
- a CNAME for a subdomain such as
pay.acme.com(recommended), or A records for a domain at the apex; - a TXT record
_ownrecord-challenge.{host}with the valueownrecord-verify={token}, which proves the domain is yours. The token is new for every domain added; - a TXT record of the hosting provider, when it needs its own proof because another account uses the domain.
The domain is pending until its DNS points at Ownrecord and the challenge record is in place; then
brands.domains.verify marks it verified. From then on, checkout links of the brand (the session url,
waitlist and invoice emails) use the domain, without the brand's slug: https://pay.acme.com/cs_….
A brand has at most one checkout and one portal domain, and a host belongs to one brand only. The plan limits the
custom domains of the whole organization (custom_domains.max). Needs brands:write.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
host | string | yes | The host name, e.g. pay.acme.com: one you registered, without https:// or a path. (at most 300 characters) |
purpose | one of checkout, portal | yes | checkout serves the brand's hosted checkout, portal its customer portal. |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is missing or malformed.domain_invalid: The host isn't one a brand can use (a URL, an IP address, a reserved name;details.reason), or the domain provider refused it.domain_taken: The host is attached to a brand already (this one or another).domain_purpose_taken: The brand already has a domain for this purpose.domain_unavailable: Another project or account at the hosting provider holds the domain.entitlement_required: The organization's plan allows no more custom domains.domain_provider_error: The domain provider failed; nothing was added.domain_dns_unavailable: DNS didn't answer for the challenge record; nothing was added.domain_provider_not_configured: Custom domains aren't set up on this deployment.upstream_timeout: The domain provider or DNS didn't answer in time; nothing was added.resource_not_found: No brand with this ID is visible to the request.version_conflict: The brand changed at the same time; retry.permission_denied: You can't change this brand's settings.
Examples
A checkout domain
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"host": "pay.acme-app.com",
"purpose": "checkout",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "pending",
"verifiedAt": null,
"url": "https://pay.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "pay.acme-app.com",
"label": "pay",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.pay.acme-app.com",
"label": "_ownrecord-challenge.pay",
"value": "ownrecord-verify=5e0c9a1b7d3f42e8a6b0c4d2e9f17a35",
"purpose": "ownership"
}
],
"check": {
"checkedAt": "2026-10-20T09:00:00.000Z",
"ownershipVerified": true,
"dnsConfigured": false,
"challengeVerified": false,
"problems": [
{
"code": "dns_not_configured",
"message": "The host doesn't point at Ownrecord yet. Create the DNS records below; changes can take up to a few hours."
},
{
"code": "challenge_missing",
"message": "Ownrecord can't find its _ownrecord-challenge TXT record yet. Create it with the value below to prove the domain is yours."
}
],
"simulated": false
}
}
A portal domain whose hosting provider asks for its own TXT record too
The domain is used by another account at the hosting provider, which asks for proof of ownership as well.
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"host": "billing.acme-app.com",
"purpose": "portal",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "brand_domain",
"host": "billing.acme-app.com",
"purpose": "portal",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "pending",
"verifiedAt": null,
"url": "https://billing.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "billing.acme-app.com",
"label": "billing",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.billing.acme-app.com",
"label": "_ownrecord-challenge.billing",
"value": "ownrecord-verify=c18d7e2f90ab4c3d8e5f6a7b1c2d3e4f",
"purpose": "ownership"
},
{
"type": "TXT",
"name": "_vercel.acme-app.com",
"label": "_vercel",
"value": "vc-domain-verify=billing.acme-app.com,9b1f6c2e8d3a4f5b6c7d",
"purpose": "ownership"
}
],
"check": {
"checkedAt": "2026-10-20T09:00:00.000Z",
"ownershipVerified": false,
"dnsConfigured": false,
"challengeVerified": false,
"problems": [
{
"code": "ownership_unverified",
"message": "The domain is used elsewhere on the hosting platform. Add the TXT record below to prove it's yours."
},
{
"code": "dns_not_configured",
"message": "The host doesn't point at Ownrecord yet. Create the DNS records below; changes can take up to a few hours."
},
{
"code": "challenge_missing",
"message": "Ownrecord can't find its _ownrecord-challenge TXT record yet. Create it with the value below to prove the domain is yours."
}
],
"simulated": false
}
}
brands_domains_list
List a brand's custom domains. Operation brands.domains.list · Organization level · permission brands:read · risk tier read · since M9
Lists the brand's custom domains (at most one for checkout and one for the customer portal) with their status and
the DNS records to create, and how many custom domains the organization uses against its plan's limit
(custom_domains.max, counted across all brands).
A pending domain doesn't serve anything yet; links keep using Ownrecord's own address until it is verified.
The records shown here are the general ones; brands.domains.verify asks the domain provider again and returns
the records it recommends for this domain, including a TXT record when it needs proof of ownership.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: The brand ID is malformed.resource_not_found: No brand with this ID is visible to the request.permission_denied: You can't see this brand's settings.
Examples
A verified checkout domain
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4"
}
Result output:
{
"object": "list",
"data": [
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "verified",
"verifiedAt": "2026-10-20T09:40:00.000Z",
"url": "https://pay.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "pay.acme-app.com",
"label": "pay",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.pay.acme-app.com",
"label": "_ownrecord-challenge.pay",
"value": "ownrecord-verify=5e0c9a1b7d3f42e8a6b0c4d2e9f17a35",
"purpose": "ownership"
}
],
"check": null
}
],
"usage": {
"used": 1,
"limit": 2
}
}
A checkout domain waiting for its DNS record
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4"
}
Result output:
{
"object": "list",
"data": [
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "pending",
"verifiedAt": null,
"url": "https://pay.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "pay.acme-app.com",
"label": "pay",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.pay.acme-app.com",
"label": "_ownrecord-challenge.pay",
"value": "ownrecord-verify=5e0c9a1b7d3f42e8a6b0c4d2e9f17a35",
"purpose": "ownership"
}
],
"check": null
}
],
"usage": {
"used": 1,
"limit": 2
}
}
brands_domains_remove
Remove a custom domain from a brand. Operation brands.domains.remove · Organization level · permission brands:write · risk tier write · since M9
Removes one of the brand's custom domains. Its hosted pages stop being served on it within a minute, links sent earlier that use it stop working, and new links use Ownrecord's own address (or the brand's other verified domain). The domain is then detached from Ownrecord's hosting in the background.
The domain stops counting against the plan's custom_domains.max at once, and can be added again later, to
this brand or another. Needs brands:write.
Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
host | string | yes | The domain's host name, e.g. pay.acme.com. (1–300 characters) |
reason | string | no | Why, for the audit log. (1–500 characters) |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is missing or malformed.resource_not_found: The brand isn't visible to the request, or has no domain with this host.version_conflict: The brand changed at the same time; retry.permission_denied: You can't change this brand's settings.
Example
Remove the checkout domain
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"host": "pay.acme-app.com",
"reason": "Moving checkout to pay.acme.io",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"deleted": true
}
brands_domains_verify
Check a custom domain again. Operation brands.domains.verify · Organization level · permission brands:write · risk tier write · since M9
Asks the domain provider to verify one of the brand's custom domains again, looks up the domain's
_ownrecord-challenge TXT record, and records the answer: verified once the domain is attached, its DNS points
at Ownrecord and the challenge record carries the domain's token (ownrecord-verify={token}); pending
otherwise, with the records still needed in dnsRecords and what is missing in check.problems.
A verified domain that no longer passes, for example because the challenge record was deleted, goes back to
pending: its pages stop being served and links stop using it until it is verified again. DNS changes can take a
few hours to be seen; checking again is safe at any time.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
host | string | yes | The domain's host name, e.g. pay.acme.com. (1–300 characters) |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is missing or malformed.resource_not_found: The brand isn't visible to the request, or has no domain with this host.domain_provider_error: The domain provider failed; nothing changed.domain_dns_unavailable: DNS didn't answer for the challenge record; nothing changed.domain_provider_not_configured: Custom domains aren't set up on this deployment.upstream_timeout: The domain provider or DNS didn't answer in time; nothing changed.version_conflict: The brand changed at the same time; retry.permission_denied: You can't change this brand's settings.
Examples
DNS points at Ownrecord and the challenge record is in place
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"host": "pay.acme-app.com",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "verified",
"verifiedAt": "2026-10-20T09:40:00.000Z",
"url": "https://pay.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "pay.acme-app.com",
"label": "pay",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.pay.acme-app.com",
"label": "_ownrecord-challenge.pay",
"value": "ownrecord-verify=5e0c9a1b7d3f42e8a6b0c4d2e9f17a35",
"purpose": "ownership"
}
],
"check": {
"checkedAt": "2026-10-20T09:40:00.000Z",
"ownershipVerified": true,
"dnsConfigured": true,
"challengeVerified": true,
"problems": [],
"simulated": false
}
}
Still waiting for the DNS records
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"host": "pay.acme-app.com",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "brand_domain",
"host": "pay.acme-app.com",
"purpose": "checkout",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"status": "pending",
"verifiedAt": null,
"url": "https://pay.acme-app.com",
"dnsRecords": [
{
"type": "CNAME",
"name": "pay.acme-app.com",
"label": "pay",
"value": "cname.vercel-dns.com",
"purpose": "routing"
},
{
"type": "TXT",
"name": "_ownrecord-challenge.pay.acme-app.com",
"label": "_ownrecord-challenge.pay",
"value": "ownrecord-verify=5e0c9a1b7d3f42e8a6b0c4d2e9f17a35",
"purpose": "ownership"
}
],
"check": {
"checkedAt": "2026-10-20T09:00:00.000Z",
"ownershipVerified": true,
"dnsConfigured": false,
"challengeVerified": false,
"problems": [
{
"code": "dns_not_configured",
"message": "The host doesn't point at Ownrecord yet. Create the DNS records below; changes can take up to a few hours."
},
{
"code": "challenge_missing",
"message": "Ownrecord can't find its _ownrecord-challenge TXT record yet. Create it with the value below to prove the domain is yours."
}
],
"simulated": false
}
}
brands_get
Get a brand. Operation brands.get · Organization level · permission brands:read · risk tier read · since M1
Returns one brand by its ID (brd_…): name, slug, status, branding, statement descriptor and invoice
series. A brand outside the request's scope (another organization, another entity of an entity-scoped
request, or a sibling of a brand-scoped one) is resource_not_found.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
resource_not_found: No brand with this ID is visible to the request.permission_denied: You can't see brands here.
Example
Read a brand
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
brands_go_live
Take a brand live. Operation brands.go_live · Organization level · permission brands:admin · risk tier security · since M12
Moves the brand from test mode (test_only) to live, so it can take real payments, once every item of its
go-live checklist holds (brands.go_live_checklist). The brand's live processor connection is tested at the
processor first, and the test result is recorded on the connection. If anything is missing the call fails with
go_live_requirements_unmet and details.unmet lists what. A brand that is live already is returned as is.
After this, live API keys can be created for the brand and its live checkout sessions are accepted.
Call it in live mode, with a sign-in in the last 15 minutes in the console. Security tier for agents (it needs
approval). Needs brands:admin (organization owners and admins).
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back. - Mode: live-mode keys only.
Errors
go_live_requirements_unmet: A requirement isn't met (details.unmet,details.items); the brand stays in test mode.mode_not_supported: The request is in test mode.processor_request_failed: The processor couldn't be reached for the connection test.upstream_timeout: The processor didn't answer the connection test in time.version_conflict: The brand changed at the same time; try again.resource_not_found: No such brand in your scope.livemode_not_allowed: You have no live-mode access.fresh_auth_required: Your last sign-in is older than 15 minutes.permission_denied: You can't take this brand live.
Example
Every item holds
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"brand": {
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "live",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
},
"checklist": {
"object": "go_live_checklist",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandStatus": "live",
"ready": true,
"live": true,
"items": [
{
"requirement": "plan_livemode",
"met": true,
"reason": null
},
{
"requirement": "org_status",
"met": true,
"reason": null
},
{
"requirement": "legal_accepted",
"met": true,
"reason": null
},
{
"requirement": "entity_verified",
"met": true,
"reason": null
},
{
"requirement": "invoice_settings",
"met": true,
"reason": null
},
{
"requirement": "home_registration",
"met": true,
"reason": null
},
{
"requirement": "processor_live",
"met": true,
"reason": null
},
{
"requirement": "brand_urls",
"met": true,
"reason": null
},
{
"requirement": "brand_status",
"met": true,
"reason": null
}
],
"processor": {
"connectionId": "pcon_01m4tx5nj8emwbyf7y9vcf47xd",
"processor": "stripe",
"status": "active",
"lastTestOk": true,
"lastTestAt": "2026-10-26T09:00:00.000Z"
},
"legalVersions": {
"terms": "1.0",
"dpa": "1.0"
},
"legalAccepted": {
"terms": true,
"dpa": false
}
}
}
brands_go_live_checklist
Get a brand's go-live checklist. Operation brands.go_live_checklist · Organization level · permission brands:read · risk tier read · since M12
Returns what the brand needs before it can go live, each requirement met or not with the reason:
plan_livemode: the organization's plan includes live mode;org_status: the organization is active (not restricted, suspended, closing or closed);legal_accepted: the current Terms of Service and Data Processing Agreement are accepted;entity_verified: the legal entity's tax ID is verified;invoice_settings: the entity's invoice details are complete;home_registration: the entity's home registration isregistered, with a number (live mode);processor_live: the brand has a live processor connection whose last connection test passed (going live tests it again);brand_urls: the brand has its terms and privacy URLs;brand_status: the brand is in test mode (test_only), not suspended.
Live API keys and live checkout sessions are refused until the brand is live. Reading the checklist calls no processor.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
resource_not_found: No such brand in your scope.permission_denied: You can't read this brand.
Example
Two items left
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4"
}
Result output:
{
"object": "go_live_checklist",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandStatus": "test_only",
"ready": false,
"live": false,
"items": [
{
"requirement": "plan_livemode",
"met": true,
"reason": null
},
{
"requirement": "org_status",
"met": true,
"reason": null
},
{
"requirement": "legal_accepted",
"met": false,
"reason": "An owner or admin must accept the current version of the Data Processing Agreement."
},
{
"requirement": "entity_verified",
"met": true,
"reason": null
},
{
"requirement": "invoice_settings",
"met": true,
"reason": null
},
{
"requirement": "home_registration",
"met": true,
"reason": null
},
{
"requirement": "processor_live",
"met": true,
"reason": null
},
{
"requirement": "brand_urls",
"met": false,
"reason": "The brand needs its privacy URL."
},
{
"requirement": "brand_status",
"met": true,
"reason": null
}
],
"processor": {
"connectionId": "pcon_01m4tx5nj8emwbyf7y9vcf47xd",
"processor": "stripe",
"status": "active",
"lastTestOk": true,
"lastTestAt": "2026-10-26T09:00:00.000Z"
},
"legalVersions": {
"terms": "1.0",
"dpa": "1.0"
},
"legalAccepted": {
"terms": true,
"dpa": false
}
}
brands_list
List brands. Operation brands.list · Organization level · permission brands:read · risk tier read · since M1
Lists brands, newest first. What a request sees depends on its scope: an organization-level request every
brand of every entity (filter with entityId), a request inside one entity all of that entity's brands,
and a request inside one brand only that brand.
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
entityId | ID (ent_…) | no | – |
limit | integer | no | (1–100) |
starting_after | ID (brd_…) | no | – |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A filter or pagination value is malformed.scope_mismatch:entityIdnames an entity outside the request's scope.permission_denied: You can't see brands here.
Example
Every brand of one entity
Arguments:
{
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2"
}
Result output:
{
"object": "list",
"data": [
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x5",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-labs",
"name": "Acme Labs",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "LAB",
"creditNote": "LAB-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
brands_update
Update a brand. Operation brands.update · Organization level · permission brands:write · risk tier write · since M1
Renames a brand or changes its slug, branding (logo, icon, colors, support email and URL, terms and privacy
URLs), statement descriptor or billing settings. Send only the fields to change; null clears an optional
value (for a billing setting: back to its default).
Billing settings: dunning.retryOffsetsDays (retries after a failed charge, days after the first failure,
default 1, 3, 5, 7), dunning.finalAction (unpaid, the default, or canceled after the last retry),
entitlementGraceDays (features stay on while past due, default 7), sendInvoice.graceDays (a send_invoice
invoice is overdue this many days after its due date, default 14), cardExpiryReminders (default on),
pausedEntitlements (paused subscriptions keep their features, default off) and paymentBehavior (default
for immediate changes invoiced to a card). They apply from the next step of each subscription.
Policies: breakageRecognition says when expired paid credits become breakage revenue: at_expiry (the
default) or manual, which holds them as expired credits until your finance team recognises them with a ledger
adjustment. It applies to credits that expire from then on. disputeWalletFreeze (default on) freezes the
customer's wallets when a dispute opens; a won dispute unfreezes the wallets it froze. supportRefundLimits
sets the most the support role may refund at once, per currency (100 of a currency without one; finance has no
limit). taxIdUnavailable says what a sale does when a business customer's tax ID couldn't be checked because
the register didn't answer (spec §9.1): charge_as_b2c (the default: tax is charged as for a consumer, and a
credit note can refund it once the ID validates) or block (the sale is refused with tax_id_unavailable until
the register answers). It applies to quotes from then on.
Customer portal (portalSettings): whether customers may switch plans (allowPlanChanges, along
planChangeMatrix: one row per price naming the prices it may switch to, in the same mode and currency; no row
means no switch), cancel (allowCancel, cancelBehavior period_end or immediate, collectCancelReason)
and change seats (allowQuantityChanges). The matrix is checked against the brand's prices and replaced whole.
Languages (checkoutSettings.locales): the brand's languages for hosted pages and customer emails, its default
first. A customer's own language and their browser's come first; the brand's default is the fallback.
A new slug changes the brand's checkout URLs; existing API keys keep working. The invoice series can't
change once set. Needs brands:write (organization owners and admins, or an API key with that scope).
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (brd_…) | yes | – |
name | string | no | (1–120 characters) |
slug | string | no | (3–40 characters) |
branding | object | no | – |
statementDescriptor | string | no | (5–22 characters) |
statementDescriptorSuffix | string or null | no | – |
billingSettings | object | no | Billing settings; each field: a value sets it, null resets it to the default, absent leaves it. |
policies | object | no | Accounting policies; each field: a value sets it, null resets it to the default, absent leaves it. |
portalSettings | object | no | The customer portal's settings; send only what changes. |
checkoutSettings | object | no | Hosted page settings; send only what changes. |
entity_id | ID (ent_…) | no | Optional: act inside this legal entity (ent_…) instead of the whole organization. |
brand_id | ID (brd_…) | no | Optional: act inside this brand (brd_…) instead of the whole organization. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Scope: the whole organization, or one legal entity or brand of it with
entity_idorbrand_id. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: No field to change was sent, or one is malformed; or a plan-change matrix row names a price that isn't the brand's recurring licensed price, an archived target, or a target in another mode or currency (details.issues).slug_invalid: The slug has the wrong format or is a reserved word.slug_taken: Another brand already uses this slug.resource_not_found: No brand with this ID is visible to the request.version_conflict: The brand changed at the same time; retry.permission_denied: You can't change brands here.
Examples
Set the support email and legal links
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"branding": {
"supportEmail": "help@acme.example",
"termsUrl": "https://acme.example/terms",
"privacyUrl": "https://acme.example/privacy"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": "help@acme.example",
"supportUrl": null,
"termsUrl": "https://acme.example/terms",
"privacyUrl": "https://acme.example/privacy"
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Cancel after the last of three retries
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"billingSettings": {
"dunning": {
"retryOffsetsDays": [2, 4, 7],
"finalAction": "canceled"
}
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [2, 4, 7],
"finalAction": "canceled"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Hold expired credits until finance recognises the breakage
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"policies": {
"breakageRecognition": "manual"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "manual",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Refuse sales while a business customer's tax ID can't be checked
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"policies": {
"taxIdUnavailable": "block"
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "block"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Let support refund up to €250 at once
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"policies": {
"supportRefundLimits": [
{
"amount": "250000000",
"currency": "EUR"
}
]
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [
{
"amount": "250000000",
"currency": "EUR"
}
],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["en", "hr"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
Let customers switch between Basic and Pro in the portal
Arguments:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [
{
"fromPriceId": "price_01m4tx5nj8emwbyf7y9vcf47xc",
"toPriceIds": ["price_01m4tx5nj8emwbyf7y9vcf47xd"]
},
{
"fromPriceId": "price_01m4tx5nj8emwbyf7y9vcf47xd",
"toPriceIds": ["price_01m4tx5nj8emwbyf7y9vcf47xc"]
}
],
"collectCancelReason": true
},
"checkoutSettings": {
"locales": ["de", "en"]
},
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"object": "brand",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"slug": "acme-app",
"name": "Acme App",
"status": "test_only",
"isPlatformBrand": false,
"branding": {
"logoUrl": null,
"iconUrl": null,
"primaryColor": null,
"accentColor": null,
"supportEmail": null,
"supportUrl": null,
"termsUrl": null,
"privacyUrl": null
},
"statementDescriptor": "ACME APP",
"statementDescriptorSuffix": null,
"invoiceSeries": {
"invoice": "ACM",
"creditNote": "ACM-CN"
},
"billingSettings": {
"dunning": {
"retryOffsetsDays": [1, 3, 5, 7],
"finalAction": "unpaid"
},
"entitlementGraceDays": 7,
"sendInvoice": {
"graceDays": 14
},
"cardExpiryReminders": true,
"pausedEntitlements": false,
"paymentBehavior": "allow_incomplete"
},
"policies": {
"breakageRecognition": "at_expiry",
"supportRefundLimits": [],
"disputeWalletFreeze": true,
"taxIdUnavailable": "charge_as_b2c"
},
"portalSettings": {
"allowPlanChanges": true,
"planChangeMatrix": [
{
"fromPriceId": "price_01m4tx5nj8emwbyf7y9vcf47xc",
"toPriceIds": ["price_01m4tx5nj8emwbyf7y9vcf47xd"]
},
{
"fromPriceId": "price_01m4tx5nj8emwbyf7y9vcf47xd",
"toPriceIds": ["price_01m4tx5nj8emwbyf7y9vcf47xc"]
}
],
"allowCancel": true,
"cancelBehavior": "period_end",
"collectCancelReason": true,
"allowQuantityChanges": false
},
"checkoutSettings": {
"locales": ["de", "en"],
"collectPhone": false,
"requireBusinessDetails": "auto"
},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}