Auth
GET /api/v1/auth/google
Initiates the Google OAuth 2.0 flow. Redirects the user's browser to the Google authorization page.
Response 302 Found
GET /api/v1/auth/google/callback
Handles the callback from Google. Upserts the user, generates a new API Key for the session, and redirects to /auth/callback?apiKey=... on the same origin by default. Set FRONTEND_URL only if you intentionally host the frontend on a different origin.
Google login session keys count toward the same 10 active API key limit as keys created with POST /api/v1/auth/keys. Revoke an existing key before logging in with Google again if the limit has been reached.
Query parameters
code(string) — Google authorization codestate(string) — CSRF token
Response 302 Found to frontend ?apiKey=...
OAuth callback errors return JSON through the API error handler instead of redirecting to the frontend.
Errors
| Code | Description |
|---|---|
OAUTH_STATE_MISMATCH | The callback is missing the Google authorization code, the OAuth state, the stored state cookie, or the supplied state does not match the stored state |
MAX_KEYS_REACHED | You already have 10 active keys |
GET /api/v1/auth/me
Returns the currently authenticated user. Useful for verifying a key is valid.
Response 200
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "you@example.com",
"name": "Your Name",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
}GET /api/v1/auth/keys
List your active (non-revoked) API keys, newest first. Use the returned id to revoke keys. Note: the full secret key value is never returned after creation — only its prefix.
Query parameters
| Parameter | Description |
|---|---|
limit | Page size (default: 20, max: 100) |
cursor | Pagination cursor |
Response 200
{
"data": [
{
"id": "...",
"name": "Default",
"keyPrefix": "doto_abc123",
"lastUsedAt": "2024-01-15T10:30:00.000Z",
"createdAt": "2024-01-01T00:00:00.000Z",
"revokedAt": null
}
],
"meta": { "hasMore": false }
}POST /api/v1/auth/keys
Create a new API key. The full key is returned only in this response.
Request body
{
"name": "CI Bot"
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Label for the key (default: New Key) |
Response 201
{
"data": {
"id": "...",
"name": "CI Bot",
"keyPrefix": "doto_xyz789",
"key": "doto_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"lastUsedAt": null,
"createdAt": "2024-01-15T00:00:00.000Z",
"revokedAt": null
}
}Errors
| Code | Description |
|---|---|
MAX_KEYS_REACHED | You already have 10 active keys |
DELETE /api/v1/auth/keys/:id
Revoke an API key. The key stops working immediately.
Response 200
{
"data": { "message": "API key revoked" }
}