Docs
Account, API keys and signup
Sign up, manage API keys (scopes, spend limits, expiry, IP allowlists, live and test modes), read usage and the credit ledger, and get balance alerts.
Everything about your account is an API route, free, and also available in the dashboard.
Sign up
People: enter your email address on the signup page. We email a single-use link; confirming it creates your account with 100 free credits (once per account, no card) and two keys: a live key and a test key, shown once. The same link signs in to an existing account.
AI agents: an agent without a key signs up with its human's email address:
curl -X POST https://staging.socialtap.dev/v1/agent_signup \
-H 'content-type: application/json' \
-d '{"email": "you@example.com", "name": "my-agent"}'The answer has two keys. The test key works at once: every endpoint answers from recorded responses, free (see
test mode). The live key is pending: it spends nothing and can only call GET /v1/account until the
human opens the confirmation email and confirms, which activates it and grants the free credits. Agents never get
spending power without a human. Poll GET /v1/account with the live key: api_key.status turns from pending to
active. An address that already has an account is refused: its owner creates a key for the agent in the dashboard.
Signup is throttled per IP address and per email address, and disposable email domains are refused.
Routes
| Route | What it does | Auth |
|---|---|---|
GET /v1/accountGet the account, balance and calling key | The account's balance and plan, the low-balance alert threshold, and the calling key: its mode, scopes, spend limit (with what it used this interval) and expiry. Free; never cached. A pending agent key may call it (and nothing else) to learn when its owner confirmed. | key with account:read, or the session |
PATCH /v1/accountUpdate account settings | Sets low_balance_threshold: credits.low (an event and an email to the owner) fires once each time a request takes the balance from above it to at or below it; credits.depleted fires when the balance reaches 0. Free. | key with admin, or the session |
POST /v1/agent_signupSign up as an agent: a test key now, live on confirm | For AI agents: send your human's email address and get a test key that works at once (recorded responses, free) and a live key that stays pending until the human confirms by email, which grants the free credits. Agents never get spending power without a human. An address that already has an account is refused: its owner creates keys in the dashboard. | none |
POST /v1/api_keysCreate an API key | Creates a key with the given scopes, spend limit, expiry and IP allowlist. The secret is in this answer only: store it now. A key never gets a scope its creator lacks. Free. | key with admin, or the session |
GET /v1/api_keys/{id}Get an API key | One key and its spend this interval; never its secret. Free. | key with account:read, or the session |
GET /v1/api_keysList API keys | The account's keys, newest first, revoked ones included; never their secrets. Free. | key with account:read, or the session |
DELETE /v1/api_keys/{id}Revoke an API key | Revokes a key for good (a key may revoke itself). It stops working within a minute everywhere; revoking it again changes nothing. Free. | key with admin, or the session |
PATCH /v1/api_keys/{id}Update an API key | Changes a key's name, scopes, spend limit, expiry or IP allowlist; absent fields keep their value. Takes effect within a minute everywhere. Free. | key with admin, or the session |
GET /v1/credit_transactionsList credit transactions (the ledger) | Every change to the balance, newest first, cursor-paged: grants (free credits), purchases, hourly usage roll-ups and adjustments. Per-request detail is in GET /v1/usage. Free. | key with account:read, or the session |
POST /v1/sessionConfirm an emailed link: start a session | Exchanges an emailed link's token (single use) for a dashboard session: an HttpOnly, SameSite=Strict cookie on the API origin. Confirming a sign-up creates the account, grants the free credits and returns its first live and test keys; confirming an agent signup activates the agent's live key and grants the free credits. | none |
DELETE /v1/sessionSign out | Ends the session and clears its cookie. | dashboard session |
GET /v1/sessionGet the dashboard session | The signed-in account of the session cookie (the dashboard calls it first). | dashboard session |
POST /v1/signupEmail a sign-up or sign-in link | Sends a single-use link to the address; opening it and confirming creates the account (with free credits and live and test keys) or signs in to an existing one. The answer is the same whether or not the address has an account. Used by the signup page; agents use POST /v1/agent_signup. | none |
GET /v1/usageUsage report: requests and credits over time | Requests, successes, failures, cache hits and credits charged per time bucket, optionally grouped by endpoint, key and outcome. Buckets are listed oldest first, cursor-paged. Data is complete to within about 5 minutes; credits reconcile with the ledger. Free. | key with account:read, or the session |
API keys
Send the key in the x-api-key header. A key has:
- a mode: live keys start with
st_live_and make real, billed requests; test keys start withst_test_and answer from recorded responses, free. The mode is stored with the key; the prefix is only a hint for people. - scopes, what it may call. A new key gets every scope but
adminunless you choose, and a key never gets a scope its creator lacks. Without the scope a route needs, the answer isforbiddenwithdetails.required_scope. - an optional spend limit: at most that many credits per UTC day or month. Past it, requests fail with
spend_limit_reached(HTTP 402, never retried automatically) untildetails.resets_at, even when the account still has credits. Concurrent requests can never take a key past its limit. - an optional expiry and IP allowlist (addresses or CIDR ranges, IPv4 or IPv6). An expired key, or a call
from another address, is refused with
forbidden(details.reasonsays which).
The secret is shown once, when the key is created; the API only ever shows its prefix afterwards. Changes and revocations reach every server within a minute.
| Scope | Routes that need it |
|---|---|
endpoints | the routes of its own feature (see above) |
jobs | POST /v1/jobs/{id}/cancel, POST /v1/jobs, GET /v1/jobs/{id}, GET /v1/jobs, GET /v1/jobs/{id}/results |
account:read | GET /v1/account, GET /v1/api_keys/{id}, GET /v1/api_keys, GET /v1/credit_transactions, GET /v1/events/{id}, GET /v1/events, DELETE /v1/session, GET /v1/session, GET /v1/usage, GET /v1/webhook_endpoints/{id}/deliveries, GET /v1/webhook_endpoints/{id}, GET /v1/webhook_endpoints |
admin | PATCH /v1/account, POST /v1/api_keys, DELETE /v1/api_keys/{id}, PATCH /v1/api_keys/{id}, POST /v1/events/{id}/redeliver, POST /v1/webhook_endpoints, DELETE /v1/webhook_endpoints/{id}, POST /v1/webhook_endpoints/{id}/rotate_secret, POST /v1/webhook_endpoints/{id}/test, PATCH /v1/webhook_endpoints/{id} |
Usage and the ledger
GET /v1/usage reports requests, successes, failures, cache hits and credits per hour or day, grouped by endpoint,
key or outcome. GET /v1/credit_transactions lists every change to the balance: free credits, purchases, hourly usage
and adjustments, with the balance after each.
Balance alerts
Set low_balance_threshold with PATCH /v1/account. When a request takes the balance from above it to at or
below it, the account gets a credits.low event and an email to its owner, once per crossing. credits.depleted
fires when the balance reaches 0, and api_key.spend_limit_reached the first time in an interval that a key is
refused for its spend limit.
The dashboard session
Confirming an emailed link starts a dashboard session: a random secret in a Secure, HttpOnly, SameSite=Strict
cookie with the __Host- prefix on this origin; sign in again when it ends. Only its hash is stored. The session can read and
manage the account and keys, never call data endpoints. Every change it makes must come from this origin (the API
checks the request's Origin), so another site can neither read nor drive it. Links are single use and expire after
minutes; the confirm page asks you to press a button, so mail scanners that open links can't use them up.