Platform billing tools
MCP tools for Platform billing: platform_billing_change_plan, platform_billing_get, platform_billing_holds_get, platform_billing_holds_lift, platform_billing_holds_set, platform_billing_plan_override_remove, platform_billing_plan_override_set, platform_billing_portal_sessions_create, platform_billing_settings_get, platform_billing_settings_update.
platform_billing_change_plan: Change the organization's Ownrecord planplatform_billing_get: Get the organization's Ownrecord planplatform_billing_holds_get: Get an organization's unpaid-plan escalationplatform_billing_holds_lift: Lift a hold on an organization's escalationplatform_billing_holds_set: Hold an organization's unpaid-plan escalationplatform_billing_plan_override_remove: Remove an organization's plan overrideplatform_billing_plan_override_set: Override an organization's planplatform_billing_portal_sessions_create: Open the Ownrecord billing portalplatform_billing_settings_get: Get the platform billing settingsplatform_billing_settings_update: Change the platform billing thresholds
platform_billing_change_plan
Change the organization's Ownrecord plan. Operation platform_billing.change_plan · Organization level · permission platform_plan:admin · risk tier financial · since M12
Moves the organization to another Ownrecord plan (starter, growth or scale; sandbox to go back to the
free plan) and billing interval (month or year where the plan has a yearly price):
- Upgrade with a card on file: applies now, invoiced at once with the unused time credited; the old plan stays until the payment succeeds.
- Upgrade without a card (for example from
sandbox): the answer isoutcome: checkoutwithcheckoutUrl, Ownrecord's own checkout, where you save a card and pay the first invoice. The plan changes when it is paid. - Downgrade: scheduled for the end of the current period (
outcome: scheduled), with no credit.
Plans are priced in EUR, CHF and USD: pass currency, or leave it out to keep a running paid plan's currency
(or, from the free plan, take the suggestion for your country: CHF for Switzerland and Liechtenstein, EUR for
the EU, USD otherwise). A running paid plan keeps its currency. Every paid plan includes the volume fee on live
payments, billed monthly in arrears in the plan's currency. Invoices come from Ownrecord's entity, Etna Labs AG
in Switzerland, with tax (Swiss VAT for Swiss customers, reverse charge for businesses abroad with a valid VAT
ID). Only an org_owner or billing_admin can change the plan. Dry-run it to see what happens without changing
anything.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
plan | string | yes | The plan key, e.g. growth. |
interval | one of month, year | no | The billing interval of the plan's fee. (default "month") |
currency | string | no | The subscription's currency: EUR, CHF or USD (default: the running plan's, else your country's). |
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) |
- 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: The plan key, interval or currency is missing or malformed.platform_plan_unknown: There's no self-serve plan with this key, or it has no price for the interval or currency.platform_plan_currency_fixed: A paid plan is running in another currency: it keeps its currency (move to the free plan first).platform_plan_unchanged: The organization is already on this plan and interval.platform_plan_change_pending: An upgrade is still waiting for its payment in a checkout.platform_billing_details_required: A paid plan needs the organization's VAT ID: add a legal entity, or billing details in the portal.platform_billing_unavailable: Ownrecord's plans aren't set up on this installation yet.platform_customer_missing: The organization's billing account is still being set up (dry runs).permission_denied: Only an org_owner or billing_admin changes the plan.
Examples
Upgrade from Sandbox to Growth
No card is on file, so the answer is Ownrecord's checkout.
Arguments:
{
"plan": "growth",
"interval": "month",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_plan_change",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"plan": "growth",
"interval": "month",
"currency": "EUR",
"outcome": "checkout",
"subscriptionId": "sub_01jbz3m4k5n6p7q8r9s0t1v2w6",
"effectiveAt": null,
"checkoutUrl": "https://ownrecord.io/c/ownrecord/cs_01jbz3m4k5n6p7q8r9s0t1v2w9?key=…"
}
Upgrade a Swiss organization to Growth in Swiss francs
Arguments:
{
"plan": "growth",
"interval": "month",
"currency": "CHF",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_plan_change",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"plan": "growth",
"interval": "month",
"currency": "CHF",
"outcome": "checkout",
"subscriptionId": "sub_01jbz3m4k5n6p7q8r9s0t1v2w6",
"effectiveAt": null,
"checkoutUrl": "https://ownrecord.io/c/ownrecord/cs_01jbz3m4k5n6p7q8r9s0t1v2w9?key=…"
}
Downgrade to Starter at the end of the period
Arguments:
{
"plan": "starter",
"interval": "month",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_plan_change",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"plan": "starter",
"interval": "month",
"currency": "EUR",
"outcome": "scheduled",
"subscriptionId": "sub_01jbz3m4k5n6p7q8r9s0t1v2w5",
"effectiveAt": "2026-11-01T00:00:00.000Z",
"checkoutUrl": null
}
platform_billing_get
Get the organization's Ownrecord plan. Operation platform_billing.get · Organization level · permission platform_plan:read · risk tier read · since M12
Returns the organization's own Ownrecord subscription, as Organization → Billing shows it: the current plan,
its status and period, the effective entitlements (an active override merged over the plan), usage against
each limit (limits, with over after a downgrade: nothing is deleted, creating more is blocked), the metered
volume of the current period with its volume fee so far, the cheapest plan for the last three months of volume,
the plans you can choose, and the escalation of an unpaid subscription (escalation: restricted after 14 days,
suspended after 30, unless a platform admin holds it).
Ownrecord bills organizations through its own platform brand: the plan is a subscription of the organization's
billing account there (platformCustomerId). Change the plan with platform_billing.change_plan; manage
payment methods, billing details and invoices in the billing portal (platform_billing.portal_sessions.create).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
This tool takes no arguments.
- Read-only: changes nothing;
idempotency_keyis ignored.
Errors
permission_denied: Only an org_owner, org_admin or billing_admin sees the organization's Ownrecord plan.resource_not_found: No such organization is visible to you.
Example
An organization on Growth
Arguments:
{}
Result output:
{
"object": "platform_billing",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"status": "active",
"livemode": true,
"provisioning": "ready",
"platformCustomerId": "cus_01jbz3m4k5n6p7q8r9s0t1v2w4",
"plan": {
"key": "growth",
"name": "Growth",
"status": "active",
"subscriptionId": "sub_01jbz3m4k5n6p7q8r9s0t1v2w5",
"interval": "month",
"currentPeriodEnd": "2026-11-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"scheduledChange": null,
"hasPaymentMethod": true
},
"override": null,
"entitlements": {
"api.rate_limit_rps": 100,
"assistant.enabled": true,
"assistant.messages_per_month": 1000,
"audit.retention_days": 90,
"brands.max": 3,
"custom_domains.max": 2,
"einvoicing.enabled": true,
"entities.max": 2,
"filing.reports": "full",
"jurisdictions.registered.max": 10,
"livemode": true,
"members.max": 10,
"processors.secondary": false,
"sso.enabled": false,
"subscriptions.enabled": true,
"support.level": "email",
"usage_billing.enabled": true
},
"limits": [
{
"feature": "entities.max",
"limit": 2,
"used": 1,
"atLimit": false,
"over": false
},
{
"feature": "brands.max",
"limit": 3,
"used": 3,
"atLimit": true,
"over": false
},
{
"feature": "members.max",
"limit": 10,
"used": 4,
"atLimit": false,
"over": false
},
{
"feature": "jurisdictions.registered.max",
"limit": 10,
"used": 2,
"atLimit": false,
"over": false
},
{
"feature": "custom_domains.max",
"limit": 2,
"used": 0,
"atLimit": false,
"over": false
}
],
"escalation": {
"unpaidSince": null,
"stage": null,
"next": null,
"hold": null,
"thresholds": {
"restrictAfterDays": 14,
"suspendAfterDays": 30
}
},
"usage": {
"periodStart": "2026-10-01T00:00:00.000Z",
"periodEnd": "2026-11-01T00:00:00.000Z",
"volume": {
"amount": "41250000000",
"currency": "EUR"
},
"transactions": 1375,
"estimatedVolumeFee": {
"amount": "206250000",
"currency": "EUR"
}
},
"recommendation": {
"cheapest": "growth",
"averageMonthlyVolume": {
"amount": "48000000000",
"currency": "EUR"
},
"costs": [
{
"plan": "starter",
"cost": {
"amount": "480000000",
"currency": "EUR"
}
},
{
"plan": "growth",
"cost": {
"amount": "389000000",
"currency": "EUR"
}
},
{
"plan": "scale",
"cost": {
"amount": "643000000",
"currency": "EUR"
}
}
]
},
"plans": [
{
"key": "growth",
"name": "Growth",
"highlighted": true,
"contactSales": false,
"current": true,
"trialDays": 14,
"prices": [
{
"lookupKey": "growth_monthly",
"currency": "EUR",
"interval": "month",
"kind": "licensed",
"amount": {
"amount": "149000000",
"currency": "EUR"
},
"ratePpm": null
},
{
"lookupKey": "growth_yearly",
"currency": "EUR",
"interval": "year",
"kind": "licensed",
"amount": {
"amount": "1430000000",
"currency": "EUR"
},
"ratePpm": null
},
{
"lookupKey": "growth_volume",
"currency": "EUR",
"interval": "month",
"kind": "metered",
"amount": null,
"ratePpm": "5000"
},
{
"lookupKey": "growth_monthly_chf",
"currency": "CHF",
"interval": "month",
"kind": "licensed",
"amount": {
"amount": "149000000",
"currency": "CHF"
},
"ratePpm": null
},
{
"lookupKey": "growth_volume_chf",
"currency": "CHF",
"interval": "month",
"kind": "metered",
"amount": null,
"ratePpm": "5000"
}
],
"entitlements": {
"api.rate_limit_rps": 100,
"assistant.enabled": true,
"assistant.messages_per_month": 1000,
"audit.retention_days": 90,
"brands.max": 3,
"custom_domains.max": 2,
"einvoicing.enabled": true,
"entities.max": 2,
"filing.reports": "full",
"jurisdictions.registered.max": 10,
"livemode": true,
"members.max": 10,
"processors.secondary": false,
"sso.enabled": false,
"subscriptions.enabled": true,
"support.level": "email",
"usage_billing.enabled": true
}
}
],
"currency": {
"options": ["EUR", "CHF", "USD"],
"current": "EUR",
"suggested": "EUR",
"changeable": false
},
"pendingUpgrade": null
}
platform_billing_holds_get
Get an organization's unpaid-plan escalation. Operation platform_billing.holds.get · Platform level · permission platform:read · risk tier read · since M12
Returns where an organization's unpaid-plan escalation stands (spec §37.5): its status, when its Ownrecord
subscription became unpaid, the stage the escalation set, the next change if it stays unpaid, and a platform
admin's hold. billingOwnsStatus is false while the organization is suspended for abuse or is closing or closed:
the escalation then changes nothing. Platform staff only.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
orgId | ID (org_…) | yes | The organization (org_…). |
- Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: The organization ID is missing or malformed.platform_billing_unavailable: Ownrecord's plans aren't set up on this installation yet.resource_not_found: There is no such organization.permission_denied: Only platform staff read an organization's escalation.
Example
Restricted and held there until a bank transfer arrives
Arguments:
{
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3"
}
Result output:
{
"object": "platform_billing_hold",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"status": "restricted",
"hold": {
"stage": "restricted",
"until": "2026-11-15T00:00:00.000Z",
"reason": "Paying by bank transfer; payment confirmed for 10 November",
"setBy": "usr_01jbz3m4k5n6p7q8r9s0t1v2w7"
},
"unpaidSince": "2026-10-05T09:12:00.000Z",
"stage": "restricted",
"next": {
"stage": "suspended",
"at": "2026-11-15T00:00:00.000Z"
},
"billingOwnsStatus": true
}
platform_billing_holds_lift
Lift a hold on an organization's escalation. Operation platform_billing.holds.lift · Platform level · permission platform:admin · risk tier write · since M12
Ends a platform admin's hold (platform_billing.holds.set): the organization's status follows the time since
its Ownrecord payment first failed again, at once (restricted after 14 days, suspended after 30, by default).
Lifting an organization without a hold changes nothing. Platform admins only; recorded in the audit log.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
orgId | ID (org_…) | yes | The organization (org_…). |
reason | string | yes | Why, for the audit log. (3–500 characters) |
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) |
- 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: The organization ID, stage, reason or date is missing or malformed.platform_billing_unavailable: Ownrecord's plans aren't set up on this installation yet.resource_not_found: There is no such organization.permission_denied: Only a platform_admin holds an organization's escalation.fresh_auth_required: Your last sign-in is older than 15 minutes: sign in again first.
Example
Lift a hold
Arguments:
{
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"reason": "The promised transfer didn't arrive",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_billing_hold",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"status": "suspended",
"hold": null,
"unpaidSince": "2026-10-05T09:12:00.000Z",
"stage": "suspended",
"next": null,
"billingOwnsStatus": true
}
platform_billing_holds_set
Hold an organization's unpaid-plan escalation. Operation platform_billing.holds.set · Platform level · permission platform:admin · risk tier write · since M12
Holds the escalation of an organization whose Ownrecord subscription is unpaid (spec §37.5): while the hold
applies, the organization is at most at stage. Hold it where it is to stop it getting worse, hold it at
active to lift a restriction or suspension, or give until to extend the current stage to a date. The status
changes at once. The hold ends at until, when it is lifted (platform_billing.holds.lift), or when the
subscription is paid. Platform admins only; the reason is recorded in the organization's audit log.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
orgId | ID (org_…) | yes | The organization (org_…). |
stage | one of active, restricted, suspended | yes | The most severe stage while the hold applies. |
until | date-time (ISO 8601) | no | When the hold ends (ISO 8601, in the future); left out, it lasts until lifted. |
reason | string | yes | Why, for the audit log and the support team. (3–500 characters) |
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) |
- 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: The organization ID, stage, reason or date is missing or malformed.platform_billing_hold_invalid: The hold ends in the past, or the organization's subscription isn't unpaid.platform_billing_unavailable: Ownrecord's plans aren't set up on this installation yet.resource_not_found: There is no such organization.permission_denied: Only a platform_admin holds an organization's escalation.fresh_auth_required: Your last sign-in is older than 15 minutes: sign in again first.
Example
Keep an organization restricted, not suspended, until a bank transfer arrives
Arguments:
{
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"stage": "restricted",
"until": "2026-11-15T00:00:00.000Z",
"reason": "Paying by bank transfer; payment confirmed for 10 November",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_billing_hold",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"status": "restricted",
"hold": {
"stage": "restricted",
"until": "2026-11-15T00:00:00.000Z",
"reason": "Paying by bank transfer; payment confirmed for 10 November",
"setBy": "usr_01jbz3m4k5n6p7q8r9s0t1v2w7"
},
"unpaidSince": "2026-10-05T09:12:00.000Z",
"stage": "restricted",
"next": {
"stage": "suspended",
"at": "2026-11-15T00:00:00.000Z"
},
"billingOwnsStatus": true
}
platform_billing_plan_override_remove
Remove an organization's plan override. Operation platform_billing.plan_override.remove · Platform level · permission platform:admin · risk tier security · since M13
Ends a platform admin's plan override (platform_billing.plan_override.set): the organization gets the
entitlements of the plan it pays for again, at once. Removing an organization without an override changes
nothing. Platform admins only; the reason is recorded in the organization's audit log.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
orgId | ID (org_…) | yes | The organization (org_…). |
reason | string | yes | Why, for the audit log. (3–500 characters) |
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) |
- 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
fresh_auth_required: Your last sign-in is older than 15 minutes: sign in again first.validation_failed: The organization ID or the reason is missing or malformed.resource_not_found: There is no such organization.version_conflict: The organization changed at the same time; retry.permission_denied: Only a platform_admin overrides an organization's plan.
Example
End a pilot's override
Arguments:
{
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"reason": "The pilot ended; the customer subscribed to Growth",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_plan_override",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"override": null
}
platform_billing_plan_override_set
Override an organization's plan. Operation platform_billing.plan_override.set · Platform level · permission platform:admin · risk tier security · since M13
Gives an organization the entitlements of one of Ownrecord's plans (plan, a key of data/platform/plans.yaml
such as growth or internal) whatever it pays for, until expiresAt or until removed
(platform_billing.plan_override.remove). The override names its plan: an organization on internal isn't
metered. It replaces an earlier override. Its billing (the subscription, invoices, the unpaid-plan escalation)
doesn't change. Platform admins only; the reason is recorded in the organization's audit log.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
orgId | ID (org_…) | yes | The organization (org_…). |
plan | string | yes | A plan key of data/platform/plans.yaml, e.g. growth. (1–40 characters) |
expiresAt | date-time (ISO 8601) | no | When the override ends (ISO 8601, in the future); left out, it lasts until removed. |
reason | string | yes | Why, for the audit log and the support team. (3–500 characters) |
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) |
- 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: The plan isn't one of data/platform/plans.yaml, the end date is in the past, the reason is missing, or the organization is the platform's own.resource_not_found: There is no such organization.version_conflict: The organization changed at the same time; retry.permission_denied: Only a platform_admin overrides an organization's plan.fresh_auth_required: Your last sign-in is older than 15 minutes: sign in again first.
Example
Growth for a design partner until the end of the pilot
Arguments:
{
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"plan": "growth",
"expiresAt": "2027-03-31T00:00:00.000Z",
"reason": "Design partner: Growth free until the end of the pilot",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_plan_override",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"override": {
"plan": "growth",
"planName": "Growth",
"entitlements": {
"api.rate_limit_rps": 100,
"assistant.enabled": true,
"assistant.messages_per_month": 1000,
"audit.retention_days": 90,
"brands.max": 3,
"custom_domains.max": 2,
"einvoicing.enabled": true,
"entities.max": 2,
"filing.reports": "full",
"jurisdictions.registered.max": 10,
"livemode": true,
"members.max": 10,
"processors.secondary": false,
"sso.enabled": false,
"subscriptions.enabled": true,
"support.level": "email",
"usage_billing.enabled": true
},
"reason": "Design partner: Growth free until the end of the pilot",
"setBy": "usr_01jbz3m4k5n6p7q8r9s0t1v2w7",
"expiresAt": "2027-03-31T00:00:00.000Z",
"active": true
}
}
platform_billing_portal_sessions_create
Open the Ownrecord billing portal. Operation platform_billing.portal_sessions.create · Organization level · permission platform_plan:admin · risk tier security · since M12
Makes a one-time sign-in link (15 minutes) to Ownrecord's billing portal for the organization: payment methods, billing details (the organization is a customer of Ownrecord's entity: legal name, address, VAT ID), invoices from Ownrecord as PDF, and the upcoming invoice. It is the same customer portal subscribers give their own customers. Only an org_owner or billing_admin can open it; opening it is recorded in the audit log.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
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) |
- 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: not supported.
dry_run: truefails withdry_run_not_supported.
Errors
platform_billing_unavailable: Ownrecord's plans aren't set up on this installation yet.platform_customer_missing: The organization has no billing account (the platform organization isn't billed).permission_denied: Only an org_owner or billing_admin opens the billing portal.
Example
A sign-in link to the billing portal
Arguments:
{
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_portal_session",
"orgId": "org_01jbz3m4k5n6p7q8r9s0t1v2w3",
"url": "https://ownrecord.io/portal/ownrecord/login/verify?session=psess_…&token=…",
"expiresAt": "2026-10-26T12:15:00.000Z"
}
platform_billing_settings_get
Get the platform billing settings. Operation platform_billing.settings.get · Platform level · permission platform:read · risk tier read · since M12
Returns how Ownrecord bills organizations: the days after a failed payment before an organization is restricted and suspended (spec §37.5; 14 and 30 by default), the mode organizations are billed in (live in production), and the default plan's price new organizations start on. Platform staff only.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
This tool takes no arguments.
- Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A threshold is missing or not a whole number.platform_billing_unavailable: The platform bootstrap hasn't run yet.permission_denied: Only platform staff read, and only a platform_admin changes, these settings.
Example
The defaults
Arguments:
{}
Result output:
{
"object": "platform_billing_settings",
"restrictAfterDays": 14,
"suspendAfterDays": 30,
"livemode": true,
"defaultPlanPriceId": "price_01jbz3m4k5n6p7q8r9s0t1v2w8"
}
platform_billing_settings_update
Change the platform billing thresholds. Operation platform_billing.settings.update · Platform level · permission platform:admin · risk tier write · since M12
Changes how many days after a failed Ownrecord payment an organization is restricted (restrictAfterDays,
default 14) and suspended (suspendAfterDays, default 30), from 1 to 60 days, restriction first. Organizations
move at the next escalation pass. The platform brand's own billing settings follow: payment retries and
entitlements last until the suspension. Platform admins only; audited.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
restrictAfterDays | integer | no | (1–60) |
suspendAfterDays | integer | no | (1–60) |
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) |
- 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: not supported.
dry_run: truefails withdry_run_not_supported.
Errors
validation_failed: A threshold is missing or not a whole number.platform_billing_thresholds_invalid: The thresholds are outside 1–60 days or not in order.platform_billing_unavailable: The platform bootstrap hasn't run yet.permission_denied: Only platform staff read, and only a platform_admin changes, these settings.fresh_auth_required: Your last sign-in is older than 15 minutes: sign in again first.
Example
Suspend after 45 days
Arguments:
{
"suspendAfterDays": 45,
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"object": "platform_billing_settings",
"restrictAfterDays": 14,
"suspendAfterDays": 45,
"livemode": true,
"defaultPlanPriceId": "price_01jbz3m4k5n6p7q8r9s0t1v2w8"
}