Assign or change an account's plan

Overview

Put an account on a plan, or move it to a different one. Every location under the account gets the new plan immediately.

Use this when a business signs up for a tier, upgrades, or downgrades.

You'll need the account's id and the plan_id. The plan has to be one set up for your partner; List your plans shows what's available.

All locations under the account are moved to the new plan; the previous plan is closed and the new one runs to month-end. Returns the plan and how many locations were assigned. If the plan doesn't match your billing model you get a clear 403 explaining why.

Prerequisites

  • A Partner token. See Authentication.
  • The account's id (brandId) and the plan_id to assign.

Base URL

EnvironmentURL
Productionhttps://production-api.shoutaboutus.com
Developmenthttps://development-api.shoutaboutus.com

Endpoint

POST /api/v1/partner/account/{brandId}/assign-plan

Authentication

Partner token

  • The account must be inside your account tree; otherwise 404. An id in your tree that isn't an account (for example a location) returns 403.
  • An account that belongs to another partner returns 403.
  • The plan must be set up for the account's partner, and match its billing model: plan-based partners can only assign plans set up by Shout About Us (is_admin_managed true), and usage-based partners only their own plans (is_admin_managed false). Otherwise 403.

Rate limit

This endpoint has no rate limit.

Request parameters

ParameterInTypeRequiredDescription
brandIdpathintegerYesThe account's id.

Request body

FieldTypeRequiredDescription
plan_idintegerYesThe plan to assign. Must be an existing plan set up for your partner.

Request payload

{
  "plan_id": 36
}

Response body

The payload is inside data.data.

FieldTypeDescription
accountobjectThe account's full record after the change, e.g. id, name, company_id, client_account_id, billing_id, website, address, city_id, zip, bundle_id, created_at and updated_at.
planobjectThe plan now assigned to the account.
plan.idintegerThe plan's id.
plan.plan_namestringThe plan's name.
plan.pricenumberThe plan's price.
plan.original_pricenumber or nullThe original price, or null.
plan.statusstringactive or inactive.
plan.plan_typestringplan-based or usage-based.
plan.enforcement_modestringper-location or aggregate-pool.
plan.is_admin_managedbooleantrue for plans set up by Shout About Us (plan-based partners), false for plans your partner creates (usage-based partners).
plan.descriptionstring or nullThe plan's description.
plan.plan_end_datestring or nullThe date the plan ends, or null.
plan.short_infostring or nullA one-line summary of the plan.
plan.created_atstringWhen the plan was created.
plan.updated_atstringWhen the plan was last changed.
plan.deleted_atstring or nullAlways null here.
plan.featuresarrayThe plan's features, one entry per feature.
plan.features[].idintegerThe feature row's id.
plan.features[].plan_idintegerThe plan's id.
plan.features[].feature_namestringThe feature, e.g. ai_response or review_solicitation_email.
plan.features[].enabledbooleanWhether the feature is on in this plan.
plan.features[].service_limitinteger or nullUsage-based plans: the usage limit. null means no limit.
plan.features[].limit_typestring or nullmonthly or quantity, or null.
plan.features[].included_unitsinteger or nullPlan-based plans: the units included. null means unlimited.
plan.features[].overage_ratestring or nullThe price per unit over the limit, as a decimal string, e.g. "0.0800".
plan.features[].hard_stopbooleantrue: the feature stops at its limit. false: usage over the limit is billed at overage_rate.
plan.features[].created_atstringWhen the feature row was created.
plan.features[].updated_atstringWhen the feature row was last changed.
plan.features[].deleted_atstring or nullAlways null here.
plan.plan_review_sitesarrayThe review sites on the plan, with how often reviews are collected from each.
plan.plan_review_sites[].idintegerThe row's id.
plan.plan_review_sites[].plan_idintegerThe plan's id.
plan.plan_review_sites[].review_site_idintegerThe review site's id.
plan.plan_review_sites[].pull_frequencystringHow often reviews are collected: hourly, daily, weekly or monthly.
plan.plan_review_sites[].pull_intervalintegerCollect every this many hours, days, weeks or months (1 to 30).
plan.plan_review_sites[].pull_timesarray of stringsTimes of day to collect, as HH:MM.
plan.plan_review_sites[].pull_daysarray of integers or nullDays of the week to collect (0 to 6), or null.
plan.plan_review_sites[].created_atstringWhen the row was created.
plan.plan_review_sites[].updated_atstringWhen the row was last changed.
plan.plan_review_sites[].deleted_atstring or nullAlways null here.
plan.plan_review_sites[].review_siteobjectThe review site, including id, name, link, logo and auth_type.
plan.plan_review_sites[].review_site.idintegerThe review site's id.
plan.plan_review_sites[].review_site.namestringThe review site's name.
plan.plan_review_sites[].review_site.linkstringThe review site's home page.
plan.plan_review_sites[].review_site.logostring or nullThe review site's logo URL, or null.
plan.plan_review_sites[].review_site.auth_typestring or nullHow the site connects: oauth, cookie, credential, default, restapi or null. See List supported review sites.
stores_assignedintegerThe number of the account's locations moved to the plan.

Response payload

{
  "data": {
    "data": {
      "account": {
        "id": 6021,
        "name": "Acme Brand",
        "code": "54k8vyvz",
        "company_id": 2,
        "site_url": null,
        "logo": null,
        "partner_domain": null,
        "address": "1 George St",
        "address2": null,
        "city_id": 3243,
        "country_id": null,
        "state_id": null,
        "zip": "2000",
        "company_phone": "1234567890",
        "use_sau_scrapper": null,
        "hide_response_menu": null,
        "insight_report": false,
        "billing_id": "BILL-001",
        "phone": "9876543210",
        "guid": "B3E031AB-2E2F-4B9C-8309-2BE5B102B88D",
        "bundle_id": 3,
        "billing_model": null,
        "email_templates_enabled": false,
        "contract_model": null,
        "timezone_area": null,
        "timezone_name": null,
        "website": "https://acmebrand.com",
        "created_at": "2026-10-01T09:10:31.000000Z",
        "updated_at": "2026-10-01T09:14:26.000000Z",
        "deleted_at": null,
        "client_account_id": "ACC-001"
      },
      "plan": {
        "id": 36,
        "plan_name": "Growth — Unlimited",
        "price": 2,
        "original_price": null,
        "status": "active",
        "plan_type": "plan-based",
        "enforcement_mode": "per-location",
        "is_admin_managed": true,
        "description": null,
        "plan_end_date": null,
        "short_info": null,
        "created_at": "2026-09-21T13:53:10.000000Z",
        "updated_at": "2026-09-21T13:53:10.000000Z",
        "deleted_at": null,
        "features": [
          {
            "id": 1116,
            "plan_id": 36,
            "feature_name": "ai_response",
            "enabled": true,
            "service_limit": null,
            "limit_type": null,
            "included_units": 100,
            "overage_rate": "0.0800",
            "hard_stop": false,
            "created_at": "2026-09-21T13:53:10.000000Z",
            "updated_at": "2026-09-21T13:53:10.000000Z",
            "deleted_at": null
          },
          {
            "id": 1117,
            "plan_id": 36,
            "feature_name": "review_flag",
            "enabled": true,
            "service_limit": null,
            "limit_type": null,
            "included_units": 121,
            "overage_rate": "0.0800",
            "hard_stop": false,
            "created_at": "2026-09-21T13:53:10.000000Z",
            "updated_at": "2026-09-21T13:53:10.000000Z",
            "deleted_at": null
          }
        ],
        "plan_review_sites": [
          {
            "id": 218,
            "plan_id": 36,
            "review_site_id": 1,
            "pull_frequency": "daily",
            "pull_interval": 1,
            "pull_times": [
              "06:00"
            ],
            "pull_days": null,
            "created_at": "2026-09-21T13:53:10.000000Z",
            "updated_at": "2026-09-21T13:53:10.000000Z",
            "deleted_at": null,
            "review_site": {
              "id": 1,
              "name": "Yelp",
              "link": "http://www.yelp.com",
              "logo": null,
              "auth_type": "cookie"
            }
          },
          {
            "id": 219,
            "plan_id": 36,
            "review_site_id": 3,
            "pull_frequency": "daily",
            "pull_interval": 1,
            "pull_times": [
              "06:00"
            ],
            "pull_days": null,
            "created_at": "2026-09-21T13:53:10.000000Z",
            "updated_at": "2026-09-21T13:53:10.000000Z",
            "deleted_at": null,
            "review_site": {
              "id": 3,
              "name": "Facebook",
              "link": "http://www.facebook.com",
              "logo": null,
              "auth_type": "oauth"
            }
          }
        ]
      },
      "stores_assigned": 2
    }
  }
}

The example shows two of the plan's features and two of its review sites.

Examples

Success payload

See Response payload.

Error payload

403 Plan doesn't match your billing model

The message names the rule. A usage-based partner gets Usage-based companies can only be assigned partner-managed plans.

{
  "message": "Forbidden",
  "status": "error",
  "errors": "Plan-based companies can only be assigned admin-managed plans."
}

403 Plan not set up for your partner

{
  "message": "Forbidden",
  "status": "error",
  "errors": "Plan is not available to this partner."
}

403 Not an account

{
  "message": "Forbidden",
  "status": "error",
  "errors": "Specified company is not an account."
}

403 Another partner's account

{
  "message": "Forbidden",
  "status": "error",
  "errors": "You do not have access to this account."
}

404 Account not found

{
  "message": "Not Found",
  "status": "error",
  "errors": "Account not found."
}

404 Plan not found

{
  "message": "Not Found",
  "status": "error",
  "errors": "Plan not found."
}

422 plan_id missing

{
  "message": "The plan id field is required.",
  "errors": {
    "plan_id": ["The plan id field is required."]
  }
}
StatusMeaning
200The plan is assigned to the account and its locations.
401The token is missing, expired or invalid.
403The id isn't an account, the account belongs to another partner, or the plan isn't available to your partner or doesn't match its billing model.
404The account isn't in your account tree, or the plan no longer exists.
422plan_id is missing or isn't an existing plan.
500Unexpected server error.

Example request

curl --request POST \
  --url "https://production-api.shoutaboutus.com/api/v1/partner/account/6021/assign-plan" \
  --header 'Authorization: Bearer <bearer-token>' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"plan_id": 36}'

Did this page help you?