API Documentation
v1 · base URL https://api.agentyk.xyz
Auth model
Three JWT types, all signed with the same ed25519 key (publicly verifiable at /.well-known/jwks.json):
- access — 30 min, user session, audience
api. Sent asAuthorization: Bearer …to/api/*. - refresh — 30 days, opaque (not a JWT — random base64url string), rotated on every
/api/auth/refresh. - license — 30–90 days, device-bound, audience = appId. Verified offline by SDKs against the published JWKS; clients only re-check the revocation list periodically.
Authentication
POST/api/auth/register
body: { email, password, tenantName }
POST/api/auth/login
body: { email, password }
returns: { accessToken, accessExpiresAt, refreshToken, refreshExpiresAt }
POST/api/auth/refresh
body: { refreshToken }
returns: { accessToken, ... refreshToken (rotated), ... }
POST/api/auth/logout
body: { refreshToken }
GET/api/auth/meaccess
returns: { user, tenant }
POST/api/auth/forgot
body: { email }
Always 200 (no enumeration)
POST/api/auth/reset
body: { token, newPassword }
POST/api/auth/verify-email
body: { token }
POST/api/auth/resend-verificationaccess
POST/api/auth/accept-invite
body: { token, password }
Subscriptions and credits
GET/api/subscriptions/plans
Public — pricing-page data source
GET/api/subscriptionsaccess
POST/api/subscriptions/checkoutaccess
body: { planId, redirectUrl }
returns: { checkoutUrl, molliePaymentId }
POST/api/subscriptions/cancelaccess
GET/api/credits/rates
Public — full per-engine, per-model rate card
GET/api/credits/balanceaccess
returns: { monthlyMillicents, topupMillicents, totalMillicents, monthlyResetsAt }
GET/api/credits/transactions?limit=N&before=ISOaccess
POST/api/credits/topupaccess
body: { amountEur, redirectUrl }
returns: { checkoutUrl }
GET/api/credits/auto-rechargeaccess
POST/api/credits/auto-recharge/setupaccess
body: { thresholdEur, amountEur, redirectUrl }
PATCH/api/credits/auto-rechargeaccess
body: { enabled?, thresholdEur?, amountEur? }
DELETE/api/credits/auto-rechargeaccess
Licenses
POST/api/licenses/issueaccess
body: { appId, device: { fingerprint, platform, name? }, ttlDays? }
returns: { license, expiresAt }
The 'license' field is the JWT to embed in your SDK
GET/api/licensesaccess
POST/api/licenses/:jti/revokeaccess
body: { reason? }
GET/api/licenses/revocations?since=ISO
Public — clients poll this daily
Usage and downloads
POST/api/usage/reportlicense
body: { appId, modelId?, inputTokens?, outputTokens?, cachedInputTokens?, metrics? }
returns: { ok, costMillicents, balance: { monthlyMc, topupMc, totalMc } }
Rate limited 600/min/IP
GET/api/usage/summaryaccess
GET/api/downloads/models/:modelIdlicense
returns: { url, expiresIn, objectKey }
Rate limited 30/min/IP
Team management
GET/api/team/membersaccess
GET/api/team/invitesaccess (admin)
POST/api/team/inviteaccess (admin)
body: { email, role: 'admin' | 'member' }
DELETE/api/team/invites/:idaccess (admin)
PATCH/api/team/members/:idaccess (admin)
body: { role }
DELETE/api/team/members/:idaccess (admin)
Account
GET/api/account/exportaccess
JSON dump — GDPR data portability
DELETE/api/accountaccess (owner)
body: { password }
GDPR right to erasure
GET/api/audit/events?limit=N&before=ISOaccess
Reliability
- Idempotency: on all
POSTendpoints that create payments or licenses, send anIdempotency-Keyheader (8–200 chars, unique per logical action). Duplicate requests within 24h replay the cached response. - Rate limits: auth endpoints are tightly limited (5–30/h),
/api/usage/reportis 600/min,/api/downloads/*is 30/min. 429 withRetry-Afterheader. - Errors: JSON envelope
{ error: "message" }. Standard HTTP codes (400/401/403/404/409/429/500).
Verifying license JWTs offline
Fetch the public key once at build time:
curl https://api.agentyk.xyz/.well-known/jwks.json
Embed the resulting JWK in your client. Verify any license JWT against it. Required claim checks:
iss === "https://api.agentyk.xyz"type === "license"exp > nowaud === your_app_id(e.g."agentyk-engine")jtinot in the locally-cached revocation list (refresh from/api/licenses/revocations?since=…daily)
This is hand-written reference docs. A machine-generated OpenAPI spec is on the roadmap; until then, this page is the source of truth.