Sevren docsAPI reference

Authentication

A Sevren account is an Ethereum wallet: you sign in by signing a message with it, which costs no gas. Each sign-in creates a session token, and that token is also your API key.

Credentials

Send a credential as a bearer token in the Authorization header.

HTTP
Authorization: Bearer sk-sv-user-…
Credential types
CredentialLooks likeUsed for
NoneNo headerGET /v1/catalog and GET /v1/models (open models only).
Session tokensk-sv-user-…The account API and every model. Paid models are charged to the account: holder free tokens on the model first (the free try, then the plan's tokens of the day), then credit.
Account keysk-sv-acct-…A key the operator issues for a credit account. Not used by web app accounts.

Session tokens

A wallet sign-in answers with a token and its expiresAt. The same token authorizes the account API under https://api.example.com/account and model requests under https://api.example.com/v1.

  • Lifetime: 14 days from sign-in. Using the token does not extend it; sign in again for a new one.
  • Limit: at most 20 live sessions per account. A 21st sign-in ends the oldest session.
  • Revocation: POST /account/logout ends the session it is called with.
  • Storage: Sevren keeps only a hash of each token and cannot show it again. Nothing is set in cookies, so there is no cross-site request forgery surface.
  • After expiry: the account API answers 401 invalid_session and the model API answers 401 invalid_api_key.

The token on the account page of the web app belongs to that browser session, and signing out there revokes it. For a script or server, sign in once more in another browser window, copy that session's token from the account page and close the window without signing out: each sign-in is a separate session. Keep the token in an environment variable or a secret store, never in source code or URLs.

CURL
# Check the token
curl https://api.example.com/account/me -H "Authorization: Bearer $SEVREN_API_KEY"

# Revoke the token
curl -X POST https://api.example.com/account/logout -H "Authorization: Bearer $SEVREN_API_KEY"

Wallet sign-in

Any Ethereum wallet that supports personal_sign can sign in on Robinhood Chain (chain id 4663). Ordinary accounts and contract wallets that implement ERC-1271, such as Safe, Coinbase Smart Wallet and Argent, are verified. A contract wallet that is not deployed yet (an ERC-6492 signature) cannot sign in. The first sign-in with a wallet creates its account.

On the sign-in page, Privy's wallet connector lists wallets and connects the one you pick: a browser wallet, or a mobile wallet through WalletConnect. Privy only connects the wallet. Your wallet signs the message, and the Sevren auth service verifies it; no Privy login or account is involved, and Sevren's servers receive nothing from Privy.

Wallet sign-in is built for the Sevren web app: the domain and URI in the signed message must be an origin the operator allows, which is https://app.example.com. To use a wallet account from code, sign in on the web app and use its session token. The rest of this section describes the flow so you can check exactly what your wallet is asked to sign.

FLOW
GET  https://auth.example.com/auth/wallet/config
  -> {"chainId":4663,"statement":"…","resourcePrefix":"urn:sevren:wallet:","maxMessageAgeSeconds":300,"plans":{…}}

POST https://auth.example.com/auth/siwe/nonce
  -> {"nonce":"…","expiresAt":"…"}

personal_sign(message, address)          # in the wallet

POST https://auth.example.com/auth/wallet/verify      {"message":"…","signature":"0x…"}
  -> {"assertion":"svw1.…","expiresAt":"…","purpose":"login","plan":{…}|null,"holdingBps":0}

POST https://api.example.com/account/login/wallet   {"assertion":"svw1.…"}
  -> 200 {"token":"sk-sv-user-…","expiresAt":"…","user":{…}}
  -> 201 {"token":"sk-sv-user-…","expiresAt":"…","created":true,"user":{…}}   # first sign-in: a new account

The signed message

The message follows EIP-4361 (Sign-In with Ethereum). The verifier accepts exactly this layout:

EIP-4361
app.example.com wants you to sign in with your Ethereum account:
<your EIP-55 checksummed address>

<statement from GET /auth/wallet/config>

URI: https://app.example.com
Version: 1
Chain ID: 4663
Nonce: <nonce from POST /auth/siwe/nonce>
Issued At: 2026-10-09T12:00:00.000Z
Resources:
- urn:sevren:wallet:login
  • Line endings are LF only, with no trailing newline.
  • The address is EIP-55 checksummed.
  • The first line names the page host. Without a scheme the verifier reads https; the URI line must be on the same origin.
  • The statement is exactly the statement from GET /auth/wallet/config, and Chain ID is its chainId.
  • Issued At must be no older than maxMessageAgeSeconds, and the nonce works once.
  • There is exactly one resource, urn:sevren:wallet:login. A message without it, or with another urn:sevren:wallet: resource, answers 400 invalid_resource.

The assertion returned by /auth/wallet/verify is valid for 5 minutes and works once. It carries a keyed pseudonym of the address and the holder plan, never the address itself.

Who sees the address

The auth service at https://auth.example.com verifies the signature and reads the wallet's share of the Sevren token supply at both the finalized and the latest block, which makes a flash loan useless for reaching a plan. The account service at https://api.example.com only receives the pseudonym and the plan — your address stays out of your account. Privy's wallet connector and, for mobile wallets, WalletConnect may see the address too; see Privacy.

Token-gated models

A model with access token_gated or nft_gated also needs an entitlement from the gate service in the X-Sevren-Entitlement header, unless the operator granted it to an account. The live catalog on the Models page shows whether any model is gated and what its gate requires.