Authenticate and receive tokens
/v1/auth/loginPublic password authentication for platform admins, rate-limited to 5 per 15 minutes per IP. On success returns either a fully-bound access token (single Account — landing on that Account's first Application) or, for multi-Account users, a pre-auth token plus an Accounts list requiring a follow-up select-account call; an administrator who holds a second factor gets neither until a /v1/auth/mfa/challenge/* call answers the mfa_challenge returned with requires_mfa_challenge: true, unless the ca_mfa_trusted_device cookie names a device they asked to be remembered on; entering a single Account that requires a factor the admin lacks answers mfa_enrollment_pending with the session while the grace window lasts and requires_mfa_enrollment with an enrollment continuation (/v1/auth/login/mfa-enroll/*) after it; the refresh token rides an HttpOnly cookie alongside a session marker, and a pre-auth token sets its own cookie. After 5 failed attempts the user is locked out for escalating windows (15/30/45/60 minutes), and 401 is returned for bad credentials, a locked, deactivated, or unverified account; 403 for an admin with no Account membership. access_token is Bearer, TTL 900s.
Request body
application/json
emailstring Required User email address
passwordstring Required User password
include_permissionsboolean Optional Include effective permissions in the access token claims (opt-in cache)
rememberboolean Optional Keep the session on this device: persist the refresh cookie across browser restarts. When false (default), a session cookie is issued and the browser drops it on close.
Responses
application/json
data *LoginResponseDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
Rate limit
Returned object
curl -X POST "https://auth.canopy-io.com/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{ "email": "string", "password": "string", "include_permissions": false, "remember": false }'
{ "data": { "mfa_enrollment_pending": false, "grace_expires_at": "2026-04-20T12:00:00.000Z", "requires_mfa_enrollment": false, "mfa_enrollment": { "enrollment_token": "string", "available_factors": [ "totp" ], "totp": { "otpauth_uri": "string", "manual_entry_key": "string" } }, "requires_account_selection": false, "requires_mfa_challenge": false, "mfa_challenge": { "challenge_token": "string", "available_factors": [ "totp" ], "expires_at": "2026-04-20T12:00:00.000Z" }, "device_remembered": false, "recovery_codes": [ "string" ], "expires_in": 0, "user": { "id": "string", "email": "string", "first_name": "string", "last_name": "string" }, "access_token": "string", "token_type": "string", "default_environment_slug": "string", "accounts": [ { "account_id": "string", "account_name": "string", "account_slug": "string", "account_role": "string", "applications": [ { "id": "string", "name": "string", "slug": "string" } ] } ], "pending_account_creation": false } }
Tell us how we can improve this guide.