Two ways in. A bearer token for a signed-in person. An API key for a server talking to Dyva on its own.
Log in, get a token pair back. The access token goes on every request; the refresh token gets you a new pair when it expires.
/v1/auth/loginEmail and password in. Access token, refresh token, and your profile out.
Route and method verified directly against the live ts-api source on August 13, 2026.
Request body (2)
emailstringRequiredpasswordstringRequiredResponse
Illustrative example, not a captured response{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "usr_9f3a1b2c4d5e",
"email": "[email protected]",
"display_name": "Ada Lovelace",
"username": "ada_lovelace",
"tier": "free",
"role": "user"
}
}Examples (4)
curl -X POST https://api.dyva.ai/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "your-password"
}'Accounts with two-factor turned on get a different shape back: requires_2fa instead of tokens. Collect the code, then complete sign-in with the temp token.
{
"requires_2fa": true,
"temp_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}Put it in the Authorization header on every request.
curl https://api.dyva.ai/v1/dyvas \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."A 401 on a valid account usually means the access token expired. Trade the refresh token for a new pair. Each refresh token works once.
/v1/auth/refreshRefresh token in. New access and refresh token pair out.
Route and method verified directly against the live ts-api source on August 13, 2026.
Request body (1)
refresh_tokenstringRequiredResponse
Illustrative example, not a captured response{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}Examples (4)
curl -X POST https://api.dyva.ai/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{ "refresh_token": "eyJhbGciOiJSUzI1NiIs..." }'401 on a fresh refresh token too? See Error Handling.
No login step, no expiry by default. Built for a backend that calls Dyva on its own schedule. Create one from Settings or with the API below.
/v1/api-keysCreates a key. The full value is returned once, at creation, and never again. Only a short prefix is stored for display afterward.
Route and method verified directly against the live ts-api source on August 13, 2026.
Request body (2)
namestringOptionalscopesstring[]OptionalResponse
Illustrative example, not a captured response{
"id": "key_9f3a1b2c4d5e",
"name": "Production backend",
"prefix": "rk_9f3a1b2c",
"scopes": ["read", "chat"],
"created_at": "2026-03-09T12:00:00Z",
"key": "rk_9f3a1b2c4d5e6f7089abcdef0123456789..."
}Examples (4)
curl -X POST https://api.dyva.ai/v1/api-keys \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Production backend",
"scopes": ["read", "chat"]
}'Same header, same as a bearer token. Dyva reads either one from Authorization.
curl https://api.dyva.ai/v1/dyvas \
-H "Authorization: Bearer rk_9f3a1b2c4d5e6f7089abcdef0123456789..."/v1/api-keysLists your keys. Each entry carries the display prefix only. The full value never comes back after creation.
Route and method verified directly against the live ts-api source on August 13, 2026.
Response
Illustrative example, not a captured response[
{
"id": "key_9f3a1b2c4d5e",
"name": "Production backend",
"prefix": "rk_9f3a1b2c",
"scopes": ["read", "chat"],
"last_used_at": "2026-03-09T21:34:12Z",
"created_at": "2026-03-09T12:00:00Z"
}
]/v1/api-keys/:idRevokes a key immediately. Requests using it fail right after.
Route and method verified directly against the live ts-api source on August 13, 2026.
Path and query parameters (1)
idstringRequiredResponse
Illustrative example, not a captured responseHTTP/1.1 204 No ContentEvery token and key is a secret. Whoever holds it gets full access until it’s revoked.