The Subby API authenticates every request with an API key sent as a Bearer token over HTTPS. Requests without a valid key fail with 401 Unauthorized. Plain HTTP requests are refused.
curl "https://api.mysubbyapp.com/v1/account" \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"
Key types
| Prefix | Type | Environment | Where it may be used |
|---|---|---|---|
sk_test_ |
Secret key | Sandbox | Your server only |
sk_live_ |
Secret key | Live | Your server only |
pk_test_ |
Publishable key | Sandbox | Browser, WordPress plugin or Shopify app |
pk_live_ |
Publishable key | Live | Browser, WordPress plugin or Shopify app |
rk_test_ |
Restricted key | Sandbox | Your server, or a service that needs limited access |
rk_live_ |
Restricted key | Live | Your server, or a service that needs limited access |
whsec_ |
Webhook signing secret | Per endpoint | Your webhook handler, to verify signatures |
Secret keys can do everything your account can do through the API. Restricted keys can only do what you allow. Publishable keys initialise @mysubbyapp/checkout and the WordPress or Shopify integrations. They cannot create sessions or grant access — your server still uses a secret key for POST /checkout-sessions. Add each frontend origin to the publishable key's domain allow-list.
Keys are tied to one environment
A sandbox key only works against https://sandbox-api.mysubbyapp.com/v1 and a live key only works against https://api.mysubbyapp.com/v1. Using the wrong one returns:
{
"success": false,
"error": {
"type": "authentication_error",
"code": "key_environment_mismatch",
"message": "This is a live key, but the request was sent to the sandbox API. Use a sk_test_ key or send the request to the live API.",
"request_id": "req_8Hk2LmQp4",
"doc_url": "https://docs.mysubbyapp.com/errors#key_environment_mismatch"
}
}
This protects you from creating real charges while testing, and from polluting live data with test records.
Getting your keys
- Sign in to the Subby dashboard.
- Go to Developers → API keys.
- Use the environment switch to pick Sandbox or Live.
Sandbox keys are available as soon as you sign up. Live keys appear once your live access request is approved.
A secret key is shown in full only once, when it is created. After that the dashboard shows the prefix and last four characters. If you lose a key, roll it.
Restricted keys
Create a restricted key when a service only needs part of the API, such as an analytics job that reads subscriptions or a support tool that can pause them.
Each resource can be set to None, Read or Write (write includes read):
| Scope | Covers |
|---|---|
plans |
Plans |
customers |
Customers and their payment method summaries |
subscriptions |
Subscriptions, including pause, resume and cancel |
charges |
Charges and manual retries |
checkout_sessions |
Hosted checkout sessions |
nudges |
Sending and listing nudges |
webhooks |
Webhook endpoints and events |
usage |
Usage and your Subby invoices (read only) |
A request outside a restricted key's scopes fails with 403 and the code insufficient_scope. The error message names the scope that was missing.
Rolling and revoking keys
Roll a key when it may have been exposed or when someone with access leaves your team. Rolling creates a new key and lets you choose how long the old one keeps working: immediately, 1 hour, 24 hours or 7 days. That gives you time to deploy the new key without downtime.
Revoke a key to stop it working right away. Revoked keys return 401 with the code key_revoked.
Every key shows Last used, so you can find and remove keys nobody uses.
Keeping keys safe
- Store keys in environment variables or a secrets manager, never in source code.
- Never send secret or restricted keys to browsers or mobile apps. Use a publishable key with checkout sessions for anything customer-facing.
- Give each service its own restricted key with the smallest scope it needs.
- Roll keys on a schedule and whenever a team member with access leaves.
- If a live key leaks, roll it immediately and email security@mysubbyapp.com.
Request IDs
Every response includes an X-Request-Id header, and every error body includes request_id. Include it when you contact support so we can find the exact request.