Plan list (account)

Overview

Get every plan assigned to a given company (account) via the company_plans pivot, including each plan's features, feature options, and plan-level review sites, ordered cheapest-first.

Prerequisites

  • None — this is a public route. A bearer token is optional and only used to resolve the default company_id when you omit it.

Base URL

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

Endpoint

GET /api/v1/plans/list

Authentication

  • None required — the route is public (throttled at 100 requests/min). An optional bearer token supplies the default company when company_id is omitted.

  • No authentication required. The route lives in the public group ("reference data called by the SPA before login"); returns true.

  • The endpoint scopes the target company purely by the company_id query param.

  • When you omit company_id, it falls back to the authenticated user's, and finally to 1 if no user is present.

  • Reachable scope is therefore identical for partner and account roles.

  • Whatever company_id is passed is validated only as: must be an existing account, no hierarchy/an ownership check (a check that the record sits inside your own hierarchy).

  • Pass the account company id as ?company_id=brandId.

Rate limit

  • 100 requests/min.

Query parameters

  • Query: company_id (integer, optional) — company (account) id to list plans for; must be an existing account. If omitted, defaults to the logged-in user's company, else 1.

Response

  • data.data[].id (integer)
  • data.data[].plan_name (string)
  • data.data[].price (float) — cast to float; list ordered by price ascending
  • data.data[].original_price (float|null)
  • data.data[].status (string enum)
  • data.data[].plan_type (string enum)
  • data.data[].tier_slug (string|null)
  • data.data[].enforcement_mode (string enum|null)
  • data.data[].is_admin_managed (boolean) — cast to bool
  • data.data[].description (string|null)
  • data.data[].plan_end_date (datetime|null) — cast to datetime
  • data.data[].short_info (string|null)
  • data.data[].created_at / updated_at / deleted_at (datetime|null)
  • data.data[].features[] (array) — selected cols only: id, plan_id, feature_name, enabled, included_units, limit_type, hard_stop
  • data.data[].features[].options[] (array) — selected cols only: id, plan_feature_id, feature_key, feature_value
  • data.data[].plan_review_sites[] (array, relation planReviewSites) — selected cols only: id, plan_id, review_site_id, pull_frequency, pull_interval
  • data.data[].plan_review_sites[].review_site (object, relation reviewSite) — selected cols only: id, name

Returns 404 (notFoundResponse('Company not found.')) when the resolved company id does not exist. 422 on company_id validation failure; 500 (defaultErrorResponse) on a thrown exception (also logged via writeDebugLog at emergency).

200 Success · 200

{
  "data": {
    "data": [
      {
        "id": 14,
        "plan_name": "Starter",
        "price": 49.0,
        "original_price": 59.0,
        "status": "active",
        "plan_type": "usage-based",
        "tier_slug": "starter",
        "enforcement_mode": "soft",
        "is_admin_managed": false,
        "description": "Entry plan",
        "plan_end_date": null,
        "short_info": "Best for single locations",
        "created_at": "2026-05-01T10:00:00.000000Z",
        "updated_at": "2026-05-01T10:00:00.000000Z",
        "deleted_at": null,
        "features": [
          {
            "id": 81,
            "plan_id": 14,
            "feature_name": "ai_response",
            "enabled": 1,
            "included_units": 100,
            "limit_type": "monthly",
            "hard_stop": 0,
            "options": [
              { "id": 5, "plan_feature_id": 81, "feature_key": "tone", "feature_value": "professional" }
            ]
          }
        ],
        "plan_review_sites": [
          {
            "id": 22,
            "plan_id": 14,
            "review_site_id": 3,
            "pull_frequency": "weekly",
            "pull_interval": 1,
            "review_site": { "id": 3, "name": "Google" }
          }
        ]
      }
    ]
  }
}

Errors

StatusMeaning
404No record matches the id you sent
422Returned on company_id validation failure
500Unexpected server error

Example request

curl --request GET \
  --url "https://production-api.shoutaboutus.com/api/v1/plans/list?company_id=123" \
  --header 'Authorization: Bearer <bearer-token>' \
  --header 'Accept: application/json'

Did this page help you?