Skip to main content

Application-user authentication

Register, verify and authenticate users of your application. Your SyAuth dashboard account is separate. Send JSON and include the OAuth client context so the same email in another workspace cannot select the wrong application.

API conventions · All endpoints · Schemas

/e/v1/register/​

Register an application user in the workspace selected by the OAuth client or workspace.

Registration requires a registration API key in X-API-Key. A developer access token, workspace API token, or OAuth client secret cannot replace it. See credentials before using this endpoint.

POST​

JSON: email (email, required), password and matching confirm_password (strings; supply both for password login), oauth_client (public client ID) and/or workspace (UUID, tenant context required), optional first_name/last_name. The SyAuth user store validates passwords with the configured 12-character/character-class rules. Custom-database mode explicitly requires password and skips SyAuth email verification.

Request / response schema: User.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
headerX-API-Keynot supplied
bodyoauth_clientnot supplied
queryapi_keynot supplied
bodyapi_keynot supplied
bodyemailnot supplied
bodypasswordnot supplied
bodyfirst_name''
bodylast_name''

Related schemas: User.

Example request body:


{
"email": "[email protected]",
"password": "ExamplePass!7264X",
"confirm_password": "ExamplePass!7264X",
"oauth_client": "PUBLIC_CLIENT_ID",
"workspace": "11111111-1111-4111-8111-111111111111"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

201 — json


{
"message": "Registration successful.",
"user": {
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
},
"requires_verification": false
}

201 — json


{
"message": "Registration successful. Please check your email to verify your account.",
"requires_verification": true
}

400 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "API key is required for registration"
}

400 — json


{
"error": "Email is required"
}

400 — json


{
"error": "Password is required"
}

400 — json


{
"error": "An account with this email already exists."
}

400 — json


{
"email": [
"Please use a different email address."
]
}

400 — json


{
"email": [
"An account with this email already exists. Please use a different email address or log in."
]
}

401 — json


{
"error": "Invalid or unauthorized API credentials."
}

403 — json


{
"error": "Invalid or unauthorized API credentials."
}

500 — json


{
"error": "Failed to create user in external database"
}

500 — json


{
"error": "An error occurred during registration"
}

503 — json


{
"error": "Registration service unavailable. Please contact support."
}

/e/v1/login/​

Authenticate an application user. This is not the dashboard platform-account login.

POST​

JSON: email (required email), password (required string), oauth_client (client context; provide it to avoid global lookup), remember_me (boolean, default false). Success may be an MFA challenge instead of tokens. Always inspect mfa_required.

Request / response schema: Login.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyoauth_clientnot supplied

Related schemas: Login, User.

Example request body:


{
"email": "[email protected]",
"password": "ExamplePass!7264X",
"oauth_client": "PUBLIC_CLIENT_ID",
"remember_me": false
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"user": {
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
},
"token": "EXAMPLE_TOKEN",
"refresh_token": "EXAMPLE_REFRESH_TOKEN",
"message": "Login successful"
}

200 — json


{
"mfa_required": true,
"mfa_ticket": "EXAMPLE_MFA_TICKET",
"mfa_methods": []
}

400 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

401 — json


{
"error": "Invalid credentials"
}

401 — json


{
"error": "Account is inactive. Please contact support."
}

503 — json


{
"error": "Authentication service unavailable. Please contact support."
}

/e/v1/logout/​

Revoke the current application session and log the user out.

Availability note: standalone access with the credential described below has a known authentication limitation. Check integration availability before relying on this operation. If it returns an unexpected 401, contact support with the endpoint and sanitized response.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

Use the application-user Bearer token. See the availability note before integrating this operation.

POST​

No JSON body required. This operation is distinct from dashboard /api/auth/logout and OAuth token revocation.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Logout successful"
}

/e/v1/user/profile/​

Read, update or delete the authenticated application-user profile.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

Use an application-user token in Authorization: Bearer.

GET​

No request body. Response uses User schema for SyAuth-managed users, or an external-user profile object for custom database users.

Request / response schema: User.

Related schemas: User.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
}

200 — json


{
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"email_verified": true,
"is_external_db_user": true
}

200 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

PATCH​

Partial User schema body. Use first_name/last_name for a portable update across stores. Password changes are rejected here; use /user/password/update/. Workspace association cannot change.

Request / response schema: User.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyfirst_namegetattr(request.user, 'first_name', '')
bodylast_namegetattr(request.user, 'last_name', '')

Related schemas: User.

Example request body:


{
"first_name": "Updated",
"last_name": "Developer"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"company": "EXAMPLE_COMPANY",
"website": "https://app.example.test/callback",
"country": "EXAMPLE_COUNTRY",
"job_title": "EXAMPLE_JOB_TITLE",
"phone_number": "EXAMPLE_PHONE_NUMBER",
"email_verified": true,
"created_at": "2026-10-26T12:00:00Z",
"updated_at": "2026-10-26T12:00:00Z",
"last_login": "2026-10-26T12:00:00Z",
"created_via_api_key": "EXAMPLE_CREATED_VIA_API_KEY",
"developer_id": "EXAMPLE_DEVELOPER_ID",
"workspace": "11111111-1111-4111-8111-111111111111",
"oauth_client": "11111111-1111-4111-8111-111111111111"
}

200 — json


{
"id": "11111111-1111-4111-8111-111111111111",
"email": "[email protected]",
"first_name": "Example",
"last_name": "Example",
"email_verified": true,
"is_external_db_user": true
}

400 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "Unable to update profile - could not find external database connection"
}

500 — json


{
"error": "Failed to update profile in external database"
}

DELETE​

Restricted to test-account email patterns by this endpoint. This is not a general self-service account-deletion API; ordinary accounts receive 403.

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

204 — json

No response body.

400 — json


{
"error": "Unable to delete account - could not find external database connection"
}

403 — json


{
"error": "Account deletion is restricted to test accounts only."
}

500 — json


{
"error": "An error occurred while deleting account"
}

500 — json


{
"error": "Failed to delete account from external database"
}

/e/v1/user/password/update/​

Change the current application-user password.

Authentication: application-user token in Authorization: Bearer APPLICATION_TOKEN.

Application-user Bearer token.

POST​

Required JSON strings: current_password, new_password, confirm_password. New values must match and satisfy configured password validators.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodycurrent_passwordnot supplied
bodynew_passwordnot supplied
bodyconfirm_passwordnot supplied

Example request body:


{
"current_password": "ExamplePass!7264X",
"new_password": "LocalDemo!8275Y",
"confirm_password": "LocalDemo!8275Y"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Password updated successfully"
}

400 — json


{
"error": "Current password, new password, and confirm password are required"
}

400 — json


{
"error": "New passwords do not match"
}

400 — json


{
"error": "Unable to update password - could not find external database connection"
}

400 — json


{
"error": "Current password is incorrect"
}

400 — json


{
"error": "EXAMPLE_ERROR"
}

500 — json


{
"error": "Failed to update password. Please try again."
}

/e/v1/password/reset/​

Request an application-user password-reset email.

POST​

JSON: required email; optional oauth_client (strongly recommended tenant context). Generic 200 responses intentionally avoid revealing account existence.

Request / response schema: PasswordResetRequest.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyoauth_clientnot supplied

Related schemas: PasswordResetRequest.

Example request body:


{
"email": "[email protected]",
"oauth_client": "PUBLIC_CLIENT_ID"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "If an account with this email exists, a password reset code has been sent."
}

200 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

/e/v1/password/reset/confirm/​

Consume a password-reset code and set a new password.

POST​

Required JSON: email, code, new_password, confirm_password; include the original oauth_client. Code must be valid for the user and purpose. Passwords must match and satisfy validators.

Request / response schema: PasswordResetConfirm.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyoauth_clientnot supplied

Related schemas: PasswordResetConfirm.

Example request body:


{
"email": "[email protected]",
"code": "EMAIL_CODE",
"new_password": "LocalDemo!8275Y",
"confirm_password": "LocalDemo!8275Y",
"oauth_client": "PUBLIC_CLIENT_ID"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Password has been reset successfully"
}

400 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "Invalid email or code"
}

400 — json


{
"error": "Invalid or expired code"
}

500 — json


{
"error": "Failed to reset password. Please try again."
}

/e/v1/email/verify/​

Verify an application-user email address.

POST​

Required JSON strings: email, code; provide the original oauth_client to scope the lookup.

Request / response schema: VerifyEmail.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyoauth_clientnot supplied

Related schemas: VerifyEmail.

Example request body:


{
"email": "[email protected]",
"code": "EMAIL_CODE",
"oauth_client": "PUBLIC_CLIENT_ID"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Email verified successfully"
}

400 — json

JSON response varies with the request. See the operation requirements and linked schema; validation errors may be keyed by field name.

400 — json


{
"error": "Invalid email or code"
}

400 — json


{
"error": "Invalid or expired code"
}

/e/v1/email/verify/resend/​

Send another verification message.

POST​

Required JSON email (string); optional oauth_client tenant context. A generic success message may be returned for an unknown user.

Request fields (combine with the requirements and schema above):

LocationFieldFallback when absent
bodyemailnot supplied
bodyoauth_clientnot supplied

Example request body:


{
"email": "[email protected]",
"oauth_client": "PUBLIC_CLIENT_ID"
}

Success and error response examples

Illustrative values; conditional branches are alternatives. Fields vary with the operation and account configuration.

200 — json


{
"message": "Verification code has been sent to your email."
}

200 — json


{
"message": "If an account with this email exists, a verification code has been sent."
}

200 — json


{
"message": "Your email is already verified."
}

400 — json


{
"error": "Email is required"
}