Aller au contenu principal

Subscription Lifecycle

How subscriptions flow from request to active API key — with approval workflows, state transitions, and gateway provisioning.

Overview

Every API or MCP tool access in STOA goes through a subscription. Subscriptions connect a consumer (who wants access) to an API (what they want to access) via a plan (how much access they get).

Subscription States

StateAccessTransition FromTransition To
pendingNone — awaiting approval[*]active, revoked
activeFull API accesspending, suspendedsuspended, revoked, expired
suspendedBlocked temporarilyactiveactive, revoked
revokedPermanently cancelledpending, active, suspendedTerminal
expiredAuto-expiredactiveTerminal

API Key Format

When a subscription is approved, STOA generates a unique API key:

stoa_sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
└──────┘ └──────────────────────────────────┘
prefix 32 hex characters (128 bits entropy)
VariantPrefixUsage
REST API subscriptionstoa_sk_Standard API access via X-API-Key header
MCP server subscriptionstoa_mcp_MCP tool access via gateway

Security:

  • The full API key is returned once at creation — store it securely
  • STOA stores only a SHA-256 hash — the key cannot be recovered
  • The prefix (stoa_sk_a1b2) is stored for identification in dashboards
Configure your environment

The examples below use environment variables. Set them for your STOA instance:

export STOA_API_URL="https://api.gostoa.dev"       # Replace with your domain
export STOA_AUTH_URL="https://auth.gostoa.dev" # Keycloak OIDC provider
export STOA_GATEWAY_URL="https://mcp.gostoa.dev" # MCP Gateway endpoint

Self-hosted? Replace gostoa.dev with your domain.

Create a Subscription

Via REST API

curl -X POST "${STOA_API_URL}/v1/subscriptions" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"api_id": "billing-api",
"plan_name": "gold",
"application_name": "my-payment-app"
}'

Response:

{
"id": "sub-uuid-123",
"status": "pending",
"api_key": "stoa_sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"api_key_prefix": "stoa_sk_a1b2",
"api_name": "billing-api",
"plan_name": "gold",
"created_at": "2026-02-13T10:00:00Z"
}
Save Your API Key

The api_key field is only returned once. Copy it to a secure location (e.g., Infisical, environment variable). It cannot be retrieved later — only rotated.

Via Developer Portal

  1. Browse the API Catalog at portal.<YOUR_DOMAIN>
  2. Click Subscribe on any API
  3. Select a plan (e.g., Gold, Silver, Community)
  4. Name your application
  5. Click Request Access
  6. Copy your API key from the confirmation screen

Approval Workflows

Manual Approval (Default)

When a plan has requires_approval: true, subscriptions start in pending state:

# Admin: List pending subscriptions for your tenant
curl "${STOA_API_URL}/v1/subscriptions/tenant/${TENANT_ID}/pending" \
-H "Authorization: Bearer ${TOKEN}"

# Admin: Approve a subscription
curl -X POST "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/approve" \
-H "Authorization: Bearer ${TOKEN}"

Auto-Approval

Plans can define roles that bypass manual approval:

{
"slug": "community",
"name": "Community Plan",
"requires_approval": false,
"auto_approve_roles": ["tenant-admin", "devops"]
}

When requires_approval is false, subscriptions go directly to active and the API key is usable immediately.

State Transitions

Suspend a Subscription

Temporarily blocks access (e.g., billing issues, abuse detection):

curl -X POST "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/suspend" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"reason": "Payment overdue"}'

The consumer receives a 401 Unauthorized error on API calls. The API key is not deleted — it can be reactivated.

Reactivate a Subscription

curl -X POST "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/reactivate" \
-H "Authorization: Bearer ${TOKEN}"

Revoke a Subscription

Permanently cancels access — cannot be undone:

curl -X POST "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/revoke" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"reason": "Terms of service violation"}'

Gateway Provisioning

When a subscription is approved, STOA provisions the API route on the gateway. This process is tracked via a separate provisioning status:

Provisioning StatusMeaning
noneNo gateway provisioning needed
pendingQueued for provisioning
provisioningRoute being created on gateway
readyRoute active — traffic flowing
failedProvisioning error (check provisioning_error)
deprovisioningRoute being removed
deprovisionedRoute removed from gateway

Using Your API Key

Once your subscription is active and provisioning is ready, use the API key:

curl "${STOA_GATEWAY_URL}/apis/${TENANT_ID}/${API_NAME}/v1/endpoint" \
-H "X-API-Key: stoa_sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"

The gateway validates the key, checks the subscription status, and applies the plan's rate limits before forwarding to the backend.

Subscription Plans

Plans define the quotas and approval rules for subscriptions:

FieldTypeDescription
slugstringUnique identifier per tenant (e.g., gold)
rate_limit_per_secondintMax requests per second
rate_limit_per_minuteintMax requests per minute
daily_request_limitintMax requests per day
monthly_request_limitintMax requests per month
burst_limitintMax concurrent requests
requires_approvalboolWhether admin must approve
auto_approve_roleslistRoles that skip approval

Example Plans

PlanRate/minDailyMonthlyApproval
Community6010,000100,000Auto
Silver30050,0001,000,000Auto
Gold1,000500,00010,000,000Manual
EnterpriseCustomCustomCustomManual