Appearance
Sign-in
Authenticates a user with various authentication methods. If the user does not exist, the system automatically creates a new account and returns JWT tokens.
Endpoint
POST /auth/signinAuthentication: Tenant authentication required
Description
The signin endpoint allows users to authenticate using multiple authentication methods. Supported methods include password, Social providers (Facebook, Google, Apple), OTP, and guest authentication.
Auto-signup behavior:
- For Social, OTP, and guest methods: If the user does not exist, a new account is automatically created and the user is authenticated (auto-signup).
- For password method: If the user does not exist, an
INVALID_CREDENTIALSerror is returned. Password method does not support auto-signup.
After successful signin:
- The user is authenticated and receives JWT access and refresh tokens
- If the user is new (auto-signup), a user record is created automatically
- The
newUserfield indicates whether this is a new user (true) or existing user (false)
Request
The request body structure varies based on the authentication method.
Password
json
{
"method": "password",
"email": "user@example.com",
"password": "securepassword123"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "password" |
email | string | Yes | User's email address | Valid email format |
password | string | Yes | User's password | Minimum 8 characters |
Facebook
json
{
"method": "facebook",
"token": "facebook-token-here",
"tokenType": "idToken"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "facebook" |
token | string | Yes | Facebook token | Valid token string |
tokenType | string | Yes | Token type | "idToken" or "accessToken" |
Google
json
{
"method": "google",
"token": "google-token-here"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "google" |
token | string | Yes | Google token | Valid token string |
Apple
json
{
"method": "apple",
"token": "apple-token-here"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "apple" |
token | string | Yes | Apple Sign In token | Valid token string |
Guest
json
{
"method": "guest",
"token": "guest-token-here"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "guest" |
token | string | Yes | Guest token | Valid token string |
OTP
json
{
"method": "otp",
"token": "otp-token-here"
}| Parameter | Type | Required | Description | Constraints |
|---|---|---|---|---|
method | string | Yes | Authentication method | Must be "otp" |
token | string | Yes | OTP token | Valid token string |
Response
Status Code: 201 Created
The response format varies based on the authentication method. Most methods return JWT tokens, while OTP may return a different format.
Standard Response (Password, Social, Guest)
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"accessTokenExpireAt": "2025-01-15T11:30:00.000Z",
"refreshToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshTokenExpireAt": "2025-01-16T10:30:00.000Z",
"userId": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"newUser": false
}
}| Field | Type | Description |
|---|---|---|
accessToken | string | JWT access token |
accessTokenExpireAt | string | Access token expiration timestamp |
refreshToken | string | JWT refresh token |
refreshTokenExpireAt | string | Refresh token expiration timestamp |
userId | string | ULID user identifier |
newUser | boolean | true if new user, false if existing user |
OTP Response
For OTP authentication, the response format may differ and return OTP-related data instead of JWT tokens.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"data": {
"id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"createdAt": "2025-01-15T10:30:00.000Z",
"expiresAt": "2025-01-15T10:35:00.000Z",
"resendIntervalSeconds": 60
}
}| Field | Type | Description |
|---|---|---|
id | string | OTP identifier |
createdAt | string | ISO 8601 creation timestamp |
expiresAt | string | ISO 8601 expiration timestamp |
resendIntervalSeconds | number | Resend interval in seconds |
Rate Limiting
Rate limiting is applied to prevent abuse and ensure system stability. The signin endpoint has the following rate limits:
| Limit Type | Rate | Window |
|---|---|---|
| Per IP | 10 requests | 1 hour |
When rate limits are exceeded, the API returns a 429 Too Many Requests status code.
For information about rate limit headers, see Rate Limiting in the overview.
Errors
For detailed explanations of all error codes, see the Error Codes page where you can find all system errors.
400 Bad Request - Validation Error
Occurs when the request body fails validation. Common causes include invalid email format, password too short, missing required fields, or invalid method.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "The provided request data is invalid.",
"code": "VALIDATION_ERROR",
"status": 400,
"validation": {
"email": "Invalid email",
"password": "String must contain at least 8 character(s)"
}
}
}| Field | Error Message | Cause |
|---|---|---|
method | Invalid enum value | Method is not supported |
email | Invalid email | Email format is invalid |
password | String must contain at least 8 character(s) | Password is less than 8 characters |
token | Required | Token is missing for Social/OTP methods |
tokenType | Invalid enum value | Token type is not idToken or accessToken (Facebook) |
401 Unauthorized - Invalid Credentials
Occurs when authentication fails.
- Password method: The email or password is incorrect, or the user does not exist (password method does not support auto-signup).
- Social methods: The token is invalid or expired.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "Invalid credentials",
"code": "INVALID_CREDENTIALS",
"status": 401
}
}403 Forbidden - Restricted Capability
Occurs when attempting to use an authentication method that is restricted for the signin capability, or when the tenant has disabled the authentication method.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "Capability signin is restricted",
"code": "RESTRICTED_CAPABILITY",
"status": 403
}
}429 Too Many Requests - Rate Limit Exceeded
Occurs when the rate limit is exceeded. See Rate Limiting section for details.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "Too many requests",
"code": "TOO_MANY_REQUESTS",
"status": 429
}
}500 Internal Server Error
Occurs when an internal error happens during authentication. Common causes include missing provider ID after authentication method processing or other unexpected system state.
Error codes:
UNEXPECTED_STATE- Unexpected system state (e.g., missing provider ID)INTERNAL_SERVER- General internal server error
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "Missing provider ID",
"code": "UNEXPECTED_STATE",
"status": 500
}
}json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "Something went wrong on our side.",
"code": "INTERNAL_SERVER",
"status": 500
}
}OTP Errors
The following errors are specific to OTP authentication method:
404 Not Found - OTP Not Found
Occurs when the OTP token provided does not exist in the system.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "OTP not found",
"code": "OTP_NOT_FOUND",
"status": 404
}
}422 Unprocessable Entity - OTP Not Consumable
Occurs when OTP cannot be consumed. The OTP must be verified before it can be consumed.
Error codes:
OTP_NOT_CONSUMABLE- OTP is not in a consumable state (must be verified first)OTP_ALREADY_CONSUMED- OTP has already been consumed
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "OTP is not consumable",
"code": "OTP_NOT_CONSUMABLE",
"status": 422
}
}json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "OTP already consumed",
"code": "OTP_ALREADY_CONSUMED",
"status": 422
}
}500 Internal Server Error - OTP Consume Callback Error
Occurs when an error happens during OTP consume callback execution.
json
{
"meta": {
"requestId": "req-12345",
"timestamp": "2025-01-15T10:30:00.000Z"
},
"error": {
"message": "OTP consume callback error",
"code": "OTP_CONSUME_CALLBACK_ERROR",
"status": 500
}
}Notes
- Multiple authentication methods are supported:
password,facebook,google,apple,guest,otp - If the user does not exist, a new account is automatically created (auto-signup)
- The
newUserfield indicates whether the user was just created (true) or already existed (false) - For password authentication, the email is used as the provider ID
- Store the
refreshTokensecurely to refresh the access token when it expires - Refresh the access token before it expires to prevent unnecessary API requests, as requests with an expired token will fail