Plans
Change plan
Moves the workspace onto another plan straight away and records the change as a billing event, so the new limits apply immediately and the response is the refreshed limits and usage.
Billing details and a payment method have to be on file for anything other than the free plan, the workspace cannot already be on the requested plan, and workspaces billed through Shopify are refused here and have to use the Shopify variant.
POST
/api/{tenant:minlength(2)}/v{version:apiVersion}/plans/change_plan
- Authorisation
- Minimum role: OWNER
Request arguments
Request body example
Response
- Status
- 200 (OK)
- Type
- DTO_plan_limits
- Wrapper
- DTO_response_wrap
- Other statuses
- 400 (BadRequest), 403 (Forbidden)
Response body example
| Name | Type | ReadOnly | Description |
| plan | ENUM tenant_plan | | Plan |
| capped_amount | Double | | Capped amount |
DTO_capped_amount
| Name | Type | ReadOnly | Description |
| is_shopify_payment | Boolean | ReadOnly | Is shopify payment |
| current_user_count | Int32 | ReadOnly | Current user count |
| current_invite_count | Int32 | ReadOnly | Current invite count |
| require_increase | Boolean | ReadOnly | Require increase |
| minimum_required_cap | Double | ReadOnly | Minimum required cap |
| current_cap | Double | ReadOnly | Current cap |
DTO_plan_limit
| Name | Type | ReadOnly | Description |
| plan | ENUM tenant_plan | | Plan |
| price_usd | Double | | Price usd |
| price_usd_minimum | Double | | Price usd minimum |
| tickets | Int32 | | Tickets |
| ai_suggested_answers | Boolean | | Ai suggested answers |
| mailboxes | Int32 | | Mailboxes |
| kbs | Int32 | | Kbs |
| web_scraped_pages | Int32 | | Web scraped pages |
| integration_shopify_customer_card | Boolean | | Integration shopify customer card |
| integration_shopify_product_sync | Int32 | | Was a bool hardcoded true, which hid a limit that is actually enforced
(PlanSpecs.MaxNumShopifyProductsSync, PlanUsageEntity.SHOPIFY_PRODUCTS_SYNC). The public
pricing page has always advertised it as a per-plan number, so this now carries the number. |
| automation_rules | Int32 | | Automation rules |
| forms | Int32 | | Forms |
| multilingual_conversations | Boolean | | Multilingual conversations |
| ai_training_data | Boolean | | Ai training data |
| sso_google_microsoft | Boolean | | Sso google microsoft |
| api_access | Boolean | | Api access |
| lists | Int32 | | Lists |
| list_entries | Int32 | | List entries |
| fields | Int32 | | Fields |
| groups | Int32 | | Groups |
| sla_policies | Boolean | | The only feature flag here backed by real data (PlanSpec.EnableSla, per-tenant override on
PlanSpecDeviation.EnableSla, plus the global TempEnableSla kill switch). Everything below is
hardcoded true - included on every plan - and exists so the in-app plan table lists the same
features as the public pricing page. |
| statistics | Boolean | | Statistics |
| email_attachment_reading | Boolean | | Email attachment reading |
| ai_chat_bot | Boolean | | Ai chat bot |
| public_faq | Boolean | | Public faq |
| auto_replies_from_faq | Boolean | | Auto replies from faq |
| insights | Boolean | | Insights |
| chat_bot_sessions | Int32 | | NOT ENFORCED. The public pricing page advertises 500/2000/5000 sessions per month, but
nothing in the backend counts or caps them - there is no PlanSpecs column and no
PlanUsageEntity. Surfaced here so the in-app plan table can state the same thing the
customer was sold; move it to real plan data if the limit is ever implemented, and
populate DTO_plan_limits.usage for it at the same time. |
| notifications_and_mentions | Boolean | | Notifications and mentions |
| ticket_forwarding | Boolean | | Ticket forwarding |
| agents_included | Int32 | | Agents included |
| free_trial_days | Int32 | | Free trial days |
ENUM tenant_plan
| Value | Name | Description |
| 0 | UNKNOWN | UNKNOWN |
| 1 | FREE | FREE |
| 2 | SMALL | SMALL |
| 3 | MEDIUM | MEDIUM |
| 4 | LARGE | LARGE |
Generated Aug 4, 2026 18:37