Account upgrade — change account plan
Overview
Assign the selected plan to one or more accounts and (re)apply it to every store under each account. Per account, the endpoint updates or creates the CompanyPlan pointer. Then each store gets a new active StorePlan from now → end-of-month. Previously active/expired StorePlans without an issued next-invoice are closed. Accounts already on the requested plan do not count. The operation is DB-transactional, and a planChanged billing webhook fires per updated account.
Prerequisites
- A bearer token in the
Authorizationheader.
Base URL
| Environment | URL |
|---|---|
| Production | https://production-api.shoutaboutus.com |
| Development | https://development-api.shoutaboutus.com |
Endpoint
POST /api/v1/account/plan/update
Authentication
-
Requires a bearer token in the
Authorization: Bearer <bearer-token>header. -
Both (Partner or Account). Sits in the authenticated group under the
accountprefix, with no extra route-level guard. -
Scoping is entirely in the validation.
plan_idmust be a plan assignment belonging to the caller's owning partner (resolved by walking up to the plan-owning partner). Eachaccount_ids.*must be aCompanyid passing an ownership check (inside the auth user's hierarchy). -
A Partner can target any account in its tree; an Account caller can only target accounts within its own hierarchy.
-
Same params for both roles — only the reachable account set differs.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
plan_id | integer | Yes | Must be assigned (via company_plans, non-deleted) to the caller's plan-assignment partner. Else: "The selected plan is not available for your account." |
account_ids | array | Yes | Account (Company) IDs. |
account_ids.* | integer | Yes | Exists in company + within auth hierarchy (an ownership check). |
Rate limit
- No rate limit.
Request body
{
"plan_id": 3,
"account_ids": [
12,
15
]
}Response
200 Success · 200
200{
"data": {
"status": "success",
"message": "Plan updated successfully for 1 account(s) and 4 location(s). Charges will appear on next month's invoice."
}
}200 No-op (already on requested plan) · 200
200{
"data": {
"status": "error",
"message": "No accounts were updated since the selected plan is already active for all specified accounts or no active stores were found under those accounts. If you expected accounts to be updated, please verify that the account IDs are correct and that the selected plan is different from the currently active plan for those accounts."
}
}422 Plan not in partner catalog · 422
422{
"message": "The selected plan is not available for your account.",
"errors": {
"plan_id": ["The selected plan is not available for your account."]
}
}Errors
| Status | Meaning |
|---|---|
401 | The bearer token is missing, expired or invalid |
422 | Plan not in partner catalog |
500 | Unexpected server error |
Example request
curl --request POST \
--url "https://production-api.shoutaboutus.com/api/v1/account/plan/update" \
--header 'Authorization: Bearer <bearer-token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"plan_id": 3, "account_ids": [12, 15]}'Updated 10 days ago
