Browse docs

Developers

Authentication

How Soca API keys work: Bearer secret keys with sk_test_ and sk_live_ prefixes, strict mode scoping, key hygiene, 401 behavior, and per-endpoint rate limits.

Every request to the Soca API is authenticated with a secret key sent as a Bearer token:

curl https://soca.to/v1/payments \
-H "Authorization: Bearer sk_live_YOUR_SECRET_KEY"

Create and revoke keys in Dashboard → Developers. A key identifies your merchant account and its mode. There is nothing else to configure.

Test and live keys

Keys come in two prefixes: sk_test_ and sk_live_. The prefix is the mode. Everything a key creates and reads is scoped to that key's merchant and mode. Test invoices, payments, customers, meters, and events are fully isolated from live ones, and there is no way to reach across. A create request whose key mode does not match the environment it is sent to is rejected with 400 mode_mismatch.

Key hygiene

  • Server-side only. A secret key grants full API access to your account. Never ship it in a browser, mobile app, or public repository. Keep it in server environment variables.
  • Shown once. The full key value is displayed a single time at creation. Soca stores only a hash. It can never be shown again. If you lose it, create a new key.
  • Revocable. Revoke any key instantly from Dashboard → Developers. Requests with a revoked key fail with 401 unauthorized immediately.
  • Rotate by overlap. Create the new key, deploy it, then revoke the old one with no downtime.

401 behavior

A missing, malformed, invalid, or revoked key returns 401 with the standard error envelope:

{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
}
}

The header must be exactly Authorization: Bearer sk_test_... or Authorization: Bearer sk_live_.... Anything else (a missing Bearer prefix, an unrecognized token shape, an empty header) is treated as missing and gets the same 401 unauthorized response.

Rate limits

Limits are applied per caller over a sliding 60-second window, bucketed by endpoint class. When you exceed one, the API returns 429 with code rate_limited and a retry-after header (in seconds).

EndpointsLimit
GET /v1/{resource} list endpoints (payments, subscriptions, invoices, events, meters)120 requests / min
POST /v1/invoices, POST /v1/plans, POST /v1/credit_grants, POST /v1/entitlement_grants60 requests / min
POST /v1/credit_debits120 requests / min
POST /v1/meter-events (usage ingestion)600 requests / min
GET /v1/customers/{id}/entitlements/{feature_key} (access checks)600 requests / min
GET /v1/customers/{id}/credit_balance240 requests / min
POST /api/mcp (MCP server)120 requests / min

The high-volume paths, usage ingestion and entitlement checks, get 5x the standard read limit on purpose, so metering a busy product never competes with your other API traffic. Batching meter events (up to 500 per request) stretches the ingestion budget further; see the API reference.

On 429, wait for the retry-after interval and retry. Practical handling advice is in Errors and testing.

Was this page helpful?

A quick signal helps us improve the right pages.