Developer API

Your key system, driven from your own code.

vodka ships a REST API at /api/v1. Issue and revoke license keys, read per-script stats, look keys up by player, redeem, reset a device binding and manage the Discord integration, with as many scoped keys as you need and the same cryptography that protects the rest of the platform.

Create as many API keys as you need under Settings → Developer API. Name each one, scope it, and revoke or rotate it any time. The full key is shown once, at creation; vodka stores only an HMAC-SHA256 of it, never the key itself.

Authentication

Named keys. A bearer token. Your tenant only.

Create one or more keys in Settings → Developer API. Give each a name and its own scopes, and copy it once. Each carries the prefix stf_sk_ and is never stored in readable form; only an HMAC-SHA256 of it is kept, so even a database read can't recover a working key. Send it as a bearer token. Rotate whenever you like: issue a new key, move your integration across, then revoke the old one. The account a key belongs to is resolved from the key itself, never from a URL or body parameter, so a key can only ever read or change its own account's data.

Every request
Authorization: Bearer stf_sk_xxxxxxxxxxxxxxxxxxxxxxxx

Scopes

Grant a key only what it needs.

Every key is minted with an explicit set of scopes. A call without the right scope is refused with a 403 before it reaches your data.

keys:read

List a script's keys and look keys up by prefix, note or linked player.

keys:write

Issue new license keys and revoke existing ones.

hwid:write

Reset a key's device (HWID) binding so it can bind to a new machine.

users:read

Read reported player records tied to your scripts.

stats:read

Read per-script rollups: executions, unique players and active keys.

discord:manage

Redeem on a player's behalf and manage the Discord integration.

webhooks:manage

Manage webhook subscriptions for your account.

Endpoints

Everything the dashboard does, over HTTP.

The same actions you take in the dashboard, exposed as plain REST. Each endpoint checks a single scope.

POST
/api/v1/scripts/{id}/keys

Issue one or more license keys for a script.

keys:write
GET
/api/v1/scripts/{id}/keys

List a script's keys, filtered by query or status.

keys:read
POST
/api/v1/scripts/{id}/keys/{keyId}/revoke

Revoke a single key.

keys:write
POST
/api/v1/scripts/{id}/keys/{keyId}/hwid/reset

Clear a key's device binding.

hwid:write
GET
/api/v1/scripts/{id}/stats

Per-script executions, players and active keys for a range.

stats:read
GET
/api/v1/scripts/lookup

Resolve a public script by name.

keys:read
POST
/api/v1/redeem

Validate a key and link it to a player's Discord id.

discord:manage
GET
/api/v1/users

Read reported player records.

users:read

Examples

Two calls, start to finish.

Issue a 30-day key
curl -X POST https://use.vodka/api/v1/scripts/$SCRIPT_ID/keys \
  -H "Authorization: Bearer $VODKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "count": 1, "expiresInDays": 30, "note": "launch batch" }'
Fetch a script's last 7 days
curl https://use.vodka/api/v1/scripts/$SCRIPT_ID/stats?range=7d \
  -H "Authorization: Bearer $VODKA_API_KEY"

Limits & responses

Predictable limits, one response shape.

Rate-limited per key

Each key gets its own budget: up to 600 requests a minute. Go over and you get a 429 with the time the window resets, not a silent drop.

One response shape

Every response uses the same envelope, and errors carry a stable code (unauthorized, forbidden, rate_limited, not_found or bad_request) next to a human-readable message.

Keys stored as HMAC-SHA256

The plaintext key is shown once at creation. Only its HMAC-SHA256 hash is stored, so even a database read can't recover a working key.

Tenant-isolated by design

The tenant is taken from the key, never from a parameter, so a scoped key can only ever touch its own account.

Start building

Create a key and make the first call.

Developer API keys live in Settings → Developer API. Create as many as you need (name each key, pick its scopes, copy it once), and you're issuing licenses from your own code.