Skip to main content
The SkinShark API authenticates every request with a single header:
That’s it. There is no OAuth flow, no JWT bearer header, no signed request body. Keys are issued from the merchant dashboard, hashed at rest with BLAKE3, and revocable instantly.
The header name is api-key — lowercase, hyphenated. X-API-Key is rejected.

What an API key represents

An API key is bound to one merchant account. The merchant is the parent; their sub-users hang off that parent. A key authorises:
  • All /merchant/* operations on that merchant
  • Sub-user-context routes (/user/*, /market/*, /auth/ws-token) when combined with an On-Behalf-Of header to pick which sub-user to act as
Without On-Behalf-Of, sub-user-context routes run against the merchant itself: POST /market/buy without the header buys for the merchant’s own spot wallet and uses the merchant’s primary Steam trade URL. With the header, the same call is scoped to a sub-user. See Acting on behalf of a sub-user for the full mechanics.

What API keys cannot do

Some operations live in the dashboard only and are gated behind session-based JWT auth. API keys get a 403 FORBIDDEN on:
  • API key CRUD (creating, rotating, revoking other keys)
  • Webhook URL config, secret rotation, delivery inspection
  • Adjusting merchant fees (read-only over the API)
  • Account settings (password, email change, 2FA, account deletion)
  • Audit log queries and CSV exports
If you need any of these in an automated flow, file a support request. We’ll either expose it under API-key auth or build a dedicated provisioning endpoint.

IP allowlists

When you create or rotate a key in the dashboard, you can pin it to one or more source IPs. Requests from any other IP fail with:
For staging and CI, either pin the key to a NAT egress IP or leave the allowlist empty during development. Never commit a non-allowlisted key.

Storing and rotating keys

  • Treat the raw key like a password. The server only stores a hash; once you lose the raw value, you must rotate.
  • Rotate by creating a new key in the dashboard and revoking the old one. Keep both active for the deploy window so callers can roll over.
  • Set per-environment keys (production vs staging vs CI) with separate IP allowlists. Don’t reuse keys across environments.

TypeScript clients

The fastest path is the official @skinshark/sdk package, which handles the headers, envelope unwrapping, retries, and typed errors for you. Keep reading if you’d rather build your own wrapper.

With @skinshark/sdk

The constructor also accepts baseUrl (e.g. https://api-staging.skinshark.gg), timeoutMs, retries, userAgent, and a debug hook. See SDK & TypeScript types for the full surface.

With raw fetch

A minimal, typed wrapper that fails fast on envelope errors:
Use it everywhere:

Common error keys

See Errors for the full table.