Skip to Content
API ReferenceAuthentication

Authentication

Public endpoints (categories, events, markets, order book, trades, market SSE) require no credentials.

Authenticated endpoints (orders, portfolio, user SSE) require a Bearer token.

Creating an API key

  1. Log in to juhus.ee .
  2. Go to Account → API Keys.
  3. Click Create key and give it a name.
  4. Copy the key. It is shown only once.

API keys have the prefix jk_ and are tied to your account.

Using the key

Pass the key in the Authorization header on every authenticated request:

curl https://juhus.ee/api/v1/me \ -H "Authorization: Bearer jk_yourkeyhere"

401 behavior

If the token is missing, expired, or invalid the server returns:

{ "error": "Unauthorized" }

with status 401.

API keys are long-lived. Store them in environment variables, not in source code. Revoke a key immediately from Account → API Keys if it is compromised.

Rate limits

Authenticated reads share the v1-auth IP guard and the v1-user account bucket: 120 requests per 60 seconds on each tier.

Order and position mutations made with a jk_* API key use the separate per-user v1-trading token bucket. The standard policy is 120 requests/minute with a burst capacity of 10. An administrator may approve a bounded elevated or custom policy for a specific user. Every API key owned by that user shares the same allowance, so creating another key never multiplies capacity. Browser sessions remain on the standard v1-user limit.

When a limit is exceeded:

HTTP/1.1 429 Too Many Requests Retry-After: 12
{ "error": "Too many requests" }

API-key mutation responses also expose:

X-RateLimit-Limit: 600 X-RateLimit-Burst: 30 X-RateLimit-Remaining: 24

The first value is the sustained requests-per-minute policy; remaining is the number of whole burst tokens currently available. Use the market SSE stream for live market data rather than high-frequency REST polling.

Browser auth (internal)

The browser uses a short-lived minted JWT obtained from GET /api/auth/token on apps/web. This token is an internal mechanism: it is not available to external callers and is not documented here. External integrations always use jk_* API keys.