Access Control: All authentication endpoints are subject to the global middleware rules. For details on
partner-api-key,Authorizationheaders, and IP filtering, see access-control.md.
Endpoints for user registration, verification, login, and session management.
Authentication Endpoints Summary
| Endpoint | Method | Operation Name | Description |
|---|---|---|---|
/auth/register | POST | Create User | Register a new user account |
/auth/verify/send-otp | POST | Get OTP | Send verification OTP to unverified email/phone |
/auth/verify | POST | Verify OTP | Verify email/phone using OTP |
/auth/login/send-otp | POST | Get Login OTP | Send OTP for password-less login |
/auth/login-password | POST | Login Password | Authenticate using password |
/auth/login-otp | POST | Login OTP | Authenticate using OTP |
/auth/logout | POST | Logout User | Invalidate current access token |
/auth/refresh-token | POST | Refresh Token | Issue new access token using refresh token |
/auth/forgot-password | POST | Forgot Password | Send password reset link |
/auth/change-password | POST | Update Password | Change password for authenticated user |
Create User
POST /auth/register
Register a new user account.
Request Body:
{
"email": "string",
"password": "string",
"first_name": "string",
"last_name": "string",
"phone": "string"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/register" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "SecurePass123",
"first_name": "John",
"last_name": "Doe",
"phone": "+913456789010"
}'Responses:
- 201 Created:
{
"message": "User registered successfully",
"data": {
"user": {
"user_uuid": "550e8400-e29b-41d4-a716-446655440001",
"user_udai_id": "UDAI-USR-0001",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+913456789010",
"status": 0,
"created_at": "2025-07-02T10:00:00Z"
}
}
}- 400 Bad Request / 409 Conflict
{
"error": "Validation failed",
"details": {
"email": [
"Email already exists"
],
"phone": [
"Phone already exists"
]
}
}Next Step: After successful verification (POST /auth/verify) and activation, users can create organisations using POST /organisations.
Get OTP
POST /auth/verify/send-otp
Sends a verification OTP to the provided email or phone identifier. Use this before calling POST /auth/verify. Can also be used to resend an expired OTP.
Request Body:
{
"identifier_type": "email | phone",
"identifier": "string"
}| Field | Type | Description |
|---|---|---|
| identifier_type | string | “email” or “phone” |
| identifier | string | Email address or E.164 phone where OTP should be sent |
cURL Example:
curl -X POST "https://api.udai.live/v1/auth/verify/send-otp" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier_type": "email",
"identifier": "john@example.com"
}'Responses:
- 200 OK:
{
"message": "OTP sent successfully"
}Verify OTP
POST /auth/verify
Verifies the OTP sent to the user’s email or phone.
Request Body:
{
"identifier": "string",
"identifier_type": "email | phone",
"otp": "string"
}| Field | Type | Description |
|---|---|---|
| identifier | string | Email address or E.164 phone where OTP was sent |
| identifier_type | string | “email” or “phone” — determines which contact is being verified |
| otp | string | 6-digit OTP received by the user |
cURL Example (Verify Email):
curl -X POST "https://api.udai.live/v1/auth/verify" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier": "john@example.com",
"identifier_type": "email",
"otp": "482910"
}'cURL Example (Verify Phone):
curl -X POST "https://api.udai.live/v1/auth/verify" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier": "+913456789010",
"identifier_type": "phone",
"otp": "123456"
}'Responses:
- 200 OK (email):
{
"message": "Email verified successfully",
"data": {
"email_verified": true
}
}- 200 OK (phone):
{
"message": "Phone verified successfully",
"data": {
"phone_verified": true
}
}- 400 Bad Request:
{
"error": "Invalid or expired OTP"
}Get Login OTP
POST /auth/login/send-otp
Sends a one-time password (OTP) to the user’s email or phone. Use this to initiate an OTP-based login or to resend an OTP that has expired.
Request Body:
{
"identifier_type": "email | phone",
"identifier": "string"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/login/send-otp" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier_type": "email",
"identifier": "john@example.com"
}'Responses:
- 200 OK:
{
"message": "OTP sent successfully"
}- 404 Not Found:
{
"error": "No account found with the provided identifier"
}Login Password
POST /auth/login-password
Authenticate a user with a password. Supports both email and phone as the identifier.
Request Body:
{
"identifier_type": "email | phone",
"identifier": "string",
"password": "string"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/login-password" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier_type": "email",
"identifier": "john@example.com",
"password": "SecurePass123"
}'Responses:
- 200 OK:
{
"message": "Login successful",
"data": {
"user": {
"user_uuid": "550e8400-e29b-41d4-a716-446655440001",
"user_udai_id": "UDAI-USR-0001",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+913456789010",
"profile_picture": "https://example.com/profile.jpg",
"email_verified": true,
"phone_verified": true,
"is_certified_pilot": true,
"status": 1,
"created_at": "2022-01-01T00:00:00.000Z",
"updated_at": "2022-01-01T00:00:00.000Z",
"pilot_credentials": [
{
"cred_uuid": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"cred_udai_id": "UDAI-CRED-0001",
"rpc_number": "RPC987654",
"category": 2,
"sub_category": 2,
"class": 3,
"status": 1
}
],
"org_memberships": [
{
"membership_uuid": "m1a2b3c4-d5e6-7890-abcd-ef1234567890",
"membership_status": 1,
"role": 2,
"org_uuid": "2f2dd310-7e42-4a10-9a1d-8e2460f31ff6",
"org_udai_id": "UDAI-ORG-0001",
"org_name": "SkyOps Solutions",
"org_type": 1,
"org_status": 1
}
]
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"refresh_expires_in": 2592000
}
}Note: pilot_credentials is an array since a user can have multiple credentials for different asset categories.
- 401 Unauthorized:
{
"error": "Invalid credentials"
}Login OTP
POST /auth/login-otp
Authenticate a user with an OTP previously sent via /auth/login/send-otp. Supports both email and phone.
Request Body:
{
"identifier_type": "email | phone",
"identifier": "string",
"otp": "string"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/login-otp" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"identifier_type": "phone",
"identifier": "+913456789010",
"otp": "123456"
}'Responses:
- 200 OK:
{
"message": "Login successful",
"data": {
"user": {
"user_uuid": "550e8400-e29b-41d4-a716-446655440001",
"user_udai_id": "UDAI-USR-0001",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+913456789010",
"profile_picture": "https://example.com/profile.jpg",
"email_verified": true,
"phone_verified": true,
"is_certified_pilot": true,
"status": 1,
"created_at": "2022-01-01T00:00:00.000Z",
"updated_at": "2022-01-01T00:00:00.000Z",
"pilot_credentials": [
{
"cred_uuid": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"cred_udai_id": "UDAI-CRED-0001",
"rpc_number": "RPC987654",
"category": 2,
"sub_category": 2,
"class": 3,
"status": 1
}
],
"org_memberships": [
{
"membership_uuid": "m1a2b3c4-d5e6-7890-abcd-ef1234567890",
"membership_status": 1,
"role": 2,
"org_uuid": "2f2dd310-7e42-4a10-9a1d-8e2460f31ff6",
"org_udai_id": "UDAI-ORG-0001",
"org_name": "SkyOps Solutions",
"org_type": 1,
"org_status": 1
}
]
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"refresh_expires_in": 2592000
}
}Note: pilot_credentials is an array since a user can have multiple credentials for different asset categories.
- 401 Unauthorized:
{
"error": "Invalid or expired OTP"
}Logout User
POST /auth/logout
Logs out the authenticated user and invalidates the current access token.
cURL Example:
curl -X POST "https://api.udai.live/v1/auth/logout" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json"Responses:
- 200 OK:
{
"message": "Logout successful"
}Refresh Token
POST /auth/refresh-token
Issues a new access token (and a rotated refresh token) using a valid refresh token. Use this when the access token has expired to avoid forcing the user to log in again.
Request Body:
{
"refresh_token": "string"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/refresh-token" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}'Responses:
- 200 OK:
{
"message": "Token refreshed successfully",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"refresh_token": "bmV3UmVmcmVzaFRva2Vu...",
"refresh_expires_in": 2592000
}
}- 400 Bad Request:
{
"error": "Refresh token is required"
}- 401 Unauthorized:
{
"error": "Invalid or expired refresh token"
}Forgot Password
POST /auth/forgot-password
Sends a password reset link to the user’s registered email address.
Request Body:
{
"email": "adarsh@example.com"
}cURL Example:
curl -X POST "https://api.udai.live/v1/auth/forgot-password" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"email": "adarsh@example.com"
}'Responses:
- 200 OK:
{
"message": "Password reset instructions sent to your email"
}- 404 Not Found:
{
"error": "Email not found"
}Update Password
POST /auth/change-password
Changes the password for the currently authenticated user. Requires the current password for verification. Both passwords are transmitted and stored as hashes — never in plain text.
Request Body:
{
"current_password": "<hashed_current_password>",
"new_password": "<hashed_new_password>"
}| Field | Description |
|---|---|
| current_password | SHA-256 hash of the user’s current password |
| new_password | SHA-256 hash of the desired new password |
cURL Example:
curl -X POST "https://api.udai.live/v1/auth/change-password" \
-H "partner-api-key: udai_platform_abc123xyz456" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"current_password": "e3b0c44298fc1c149afb...",
"new_password": "a665a45920422f9d417e..."
}'Responses:
- 200 OK:
{
"message": "Password changed successfully"
}- 400 Bad Request:
{
"error": "New password does not meet strength requirements"
}- 401 Unauthorized:
{
"error": "Current password is incorrect"
}