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):
| Location | Field | Fallback when absent |
|---|---|---|
| header | X-API-Key | not supplied |
| body | oauth_client | not supplied |
| query | api_key | not supplied |
| body | api_key | not supplied |
| body | email | not supplied |
| body | password | not supplied |
| body | first_name | '' |
| body | last_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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | oauth_client | not supplied |
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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | first_name | getattr(request.user, 'first_name', '') |
| body | last_name | getattr(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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | current_password | not supplied |
| body | new_password | not supplied |
| body | confirm_password | not 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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | oauth_client | not 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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | oauth_client | not 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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | oauth_client | not 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):
| Location | Field | Fallback when absent |
|---|---|---|
| body | email | not supplied |
| body | oauth_client | not 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"
}