Edel has two authentication models. A person trades with an interactive browser session. A program (an agent, a bot or a market maker) trades with a scoped API key. Both credentials pass the same trader authentication and reach the same account, so an order placed by a key is decided exactly like an order placed by a person.

Human session

Interactive sign-in with a DFNS passkey or Google. The browser holds a short-lived session used while trading in the Demo, and re-authentication is another passkey approval. Built for a person at the keyboard.

API key

A scoped key sent as Authorization: Bearer <key> on every request, with no human in the loop after approval. This is the standard for automated and market-maker access, the same shape as an Alpaca or Coinbase API key. Bots trade on this same rail.

Human session

A person authenticates in the browser: a DFNS passkey (FIDO2) or a Google sign-in that resolves to the same DFNS EndUser. Login returns a short-lived DFNS EndUser bearer that authorizes private REST calls while the person trades, and every step that moves value is a fresh passkey approval. WebSocket account channels never carry the bearer; the session mints a short-lived, account-scoped ticket instead. This model is interactive by design. It expects a human to approve, so it is not the way to run an unattended strategy. For the full setup, see For Humans and the Authentication section of the introduction.

API key

An agent or a market maker authenticates with a key it holds, sent as Authorization: Bearer <key> on every request. There is no session to refresh and no human in the loop once the key exists: the program reads and trades on its own schedule. A key belongs to one account and carries a fixed set of scopes. The account owner approves a key once, in the browser, through the agent-connect device grant. See the Market maker quickstart for the end-to-end flow, and For Agents for the agent-specific runbook and the optional MCP server.

Scopes

A key carries one or both scopes. trade includes everything read allows, because an order you cannot read back is not useful. Public market data (the book, trades, marks, funding) needs no key at all. A read key that tries to place an order is refused with 403 and the reason scope_insufficient.

What a key can never do

A key can read and trade one account. It can never deposit, never withdraw, never change the account’s Canton Party binding, and never manage keys (it cannot approve another agent, list keys or revoke keys). Those actions require the human passkey session. This is a security guardrail, not a convention. The venue authorizes a key against a default-deny allowlist: a key reaches only the named read and trade routes, and every other authenticated route, including deposits, withdrawals, the Party binding and key management, refuses the key with 403 and the reason passkey_required. Because the default is deny, any authenticated route added later stays closed to keys until a reviewed change explicitly opens it. The guard runs in front of every authenticated route and is locked by tests.
The practical consequence for a market maker: a leaked or misused key is bounded. It can trade the account it was issued for, which is why you protect it, but it can never move money off the venue or take over the identity. Deposits, withdrawals and Party changes stay behind the owner’s passkey.

Lifetime, renewal and revocation

A key expires on its own. An agent key lives 24 hours by default and can be approved for as little as 5 minutes or as long as 7 days; the owner chooses the lifetime at approval time. Expiry is checked against the clock on every request, so an expired key stops working the moment it lapses.
  • Renew. There is no self-service rotation for an agent key. When a key nears expiry, run the device grant again and have the owner approve a fresh one, so every extension of access stays behind a human approval.
  • Revoke. The owner revokes a key at any time from the account with their passkey session (DELETE /v1/accounts/:accountId/api-keys/:keyId). Revocation takes effect immediately.
  • Inspect. A program reads its own key’s metadata with GET /v1/api-keys/current: the account, scopes, display prefix, expiry and state. This route returns metadata only and never the secret.
A refused key answers 401 with the closed reason expired, revoked, unknown or malformed. The response never says whether some other key would have worked; the program simply connects again.

Events arrive over WebSockets, not webhooks

Edel has no webhooks. Live data is pushed over the realtime WebSocket. Market channels (market.book, market.trades, and the rest) are open to everyone; your account events (account.orders, account.fills, account.positions, account.balance, and the rest) arrive on account channels behind a short-lived ticket you mint with your key. Do not poll REST for state the socket already pushes. See the Market maker quickstart for the connect flow and the WebSockets tab for each channel.

Shared reference

Use the REST API reference for request and response contracts, and WebSockets, not REST polling, for live data.