API Reference · Endpoints

Plans & features map

Read which plan unlocks which feature, and how API key permissions and plans combine on every request.

Two checks run on every /api/v1 request: the workspace's plan must include the feature, and the API key must have the permission the endpoint needs. This page documents both, plus the public endpoint that returns the plan map so your own UI never drifts from the server.

Get the features map

GET/api/subscriptions/features-mapTier → features mapping

Public: no authentication needed. Safe to call from a browser.

curl "https://inboxi.app/api/subscriptions/features-map"
json
{
  "success": true,
  "data": {
    "tierFeatures": {
      "starter": ["unified_inbox", "saved_replies", "tags", "widget"],
      "growth": ["unified_inbox", "saved_replies", "tags", "widget",
                 "sla_management", "lifecycle_stages", "priority_system", "automation", "full_analytics",
                 "api_access", "sdk_access", "webhooks", "push_notifications", "external_data"],
      "pro": [ "…same as growth…" ],
      "enterprise": [ "…same as pro…", "white_label" ]
    },
    "trialFeatures": ["unified_inbox", "saved_replies", "tags", "widget"],
    "featureRequiredTier": {
      "sla_management": { "tier": "growth", "label": "Growth" },
      "api_access": { "tier": "growth", "label": "Growth" },
      "webhooks": { "tier": "growth", "label": "Growth" },
      "external_data": { "tier": "growth", "label": "Growth" },
      "white_label": { "tier": "enterprise", "label": "Enterprise" },
      ...
    }
  }
}
FieldTypeRequiredDescription
tierFeaturesobjectoptionalFor each plan tier, the feature keys it includes.
trialFeaturesstring[]optionalFeatures available during the free trial (the Starter set).
featureRequiredTierobjectoptionalFor each gated feature, the lowest tier that includes it, with a display label.

Features by plan

Feature keyStarter & trialGrowthProEnterprise
unified_inbox, saved_replies, tags, widget✓✓✓✓
sla_management, lifecycle_stages, priority_system-✓✓✓
automation, full_analytics-✓✓✓
api_access, sdk_access-✓✓✓
webhooks, push_notifications, external_data-✓✓✓
white_label---✓

Growth and Pro unlock the same features; Pro differs in scale (seats, channels, credits). See Plans, credits & billing for limits and prices.

Which plan feature an API request needs

The plan check on /api/v1 depends on the key's permissions:

API key permissionsPlan feature checkedLowest plan
Include widget or *widgetStarter (and trial)
Anything else (for example only read + write)api_accessGrowth

When the check fails, the request is rejected with 403 and "code": "FEATURE_LOCKED" before the endpoint runs; see Errors.

Permission → endpoint table

The key must hold the listed permission (or *); otherwise the API answers 403 "Missing permission: …".

PermissionGrants
readGET conversations (and /chats), messages, contacts, external-data query / contact / schemas, actions list, messaging events and event status
writeSend message, trigger event, register / update / delete actions, delete external-data records and sources
external_dataPush external data (single and bulk)
webhooksCreate, list, update, delete and test webhooks; read delivery logs
widgetMarks the key as a widget key, which moves its plan check to the widget feature (Starter+). It grants no endpoint on its own.
*Every permission above.

GET /api/v1/events (the webhook event list) needs only a valid key. A new key gets read, write, webhooks, widget and external_data; narrow it in Settings › Developer Hub › API Keys when an integration needs less.

Gating your own UI

  1. 1
    Fetch the map once
    Call GET /api/subscriptions/features-map at start-up and cache it.
  2. 2
    Know the workspace tier
    Keep the tier of the workspace you integrate with in your own settings.
  3. 3
    Check before showing a feature
    Show a feature if tierFeatures[tier] contains its key; otherwise show an upgrade hint with featureRequiredTier[key].label.
  4. 4
    Still handle FEATURE_LOCKED
    Plans can change at any time, so treat a 403 FEATURE_LOCKED as the final word and refresh your cache.