AIRBNB

FRONTEND GUIDE FOR AI CODING AGENTS - PART 3 - Verification Management

This document is a part of a REST API guide for the airbnb project. It is designed for AI agents that will generate frontend code to consume the project’s backend.

This document includes the verification processes for the autheitcation flow. Please read it carefully and implement all requirements described here.

The project has 1 auth service, 1 notification service, 1 BFF service, and 6 business services, plus other helper services such as bucket and realtime. In this document you will be informed only about the auth service.

Each service is a separate microservice application and listens for HTTP requests at different service URLs.

Services may be deployed to the preview server, staging server, or production server. Therefore, each service has 3 access URLs. The frontend application must support all deployment environments during development, and the user should be able to select the target API server on the home page.

Accessing the backend

Each backend service has its own URL for each deployment environment. Users may want to test the frontend in one of the three deployments—preview, staging, or production. Please ensure that the home page includes a deployment server selection option so that, as the frontend coding agent, you can set the base URL for all services.

For the auth service, the base URLs are:

Any request that requires login must include a valid token in the Bearer authorization header.

After User Registration

Frontend should also be aware of verification after any login attempt. The login request may return a 401 or 403 with the error codes that indicates the verification needs.

{
  //...
  "errCode": "EmailVerificationNeeded",
  // or
  "errCode": "MobileVerificationNeeded",
}

Email Verification

In the registration response, check the emailVerificationNeeded property in the response root. If it is true, start the email verification flow.

After the login process, if you receive an HTTP error and the response contains an errCode with the value EmailVerificationNeeded, start the email verification flow.

  1. Call the email verification start route of the backend (described below) with the user’s email. The backend will send a secret code to the provided email address. The backend can send the email if the architect has configured a real mail service or SMTP server. During development, the backend also returns the secret code to the frontend. You can read this code from the secretCode property of the response.
  2. The secret code in the email will be a 6-digit code. Provide an input page so the user can paste this code into the frontend application. Navigate to this input page after starting the verification process. If the secretCode is sent to the frontend for testing, display it on the input page so the user can copy and paste it.
  3. The start response includes a codeIndex property. Display its value on the input page so the user can match the index in the message with the one on the screen.
  4. When the user submits the code, complete the email verification using the complete route of the backend (described below) with the user’s email and the secret code.
  5. After a successful email verification response, please check the response object to have the property ‘mobileVerificationNeeded’ as true, if so navigate to the mobile verification flow as described below. If no mobile verification is needed then just navigate the login page.

Below are the start and complete routes for email verification. These are system routes and therefore are not versioned.

POST /verification-services/email-verification/start

Purpose: Starts email verification by generating and sending a secret code.

Parameter Type Required Description
email String Yes User’s email address to verify

Example Request

{ "email": "user@example.com" }

Success Response

{
  "status": "OK", 
  "codeIndex": 1,
  // timeStamp : Milliseconds since Jan 1, 1970, 00:00:00.000 GMT
  "timeStamp": 1784578660000,
  "date": "Mon Jul 20 2026 23:17:40 GMT+0300 (GMT+03:00)",
  // expireTime: in seconds
  "expireTime": 86400,
  "verificationType": "byLink",

  // in testMode
  "secretCode": "123456",
  "userId": "user-uuid"
}

⚠️ In production, secretCode is not returned — it is only sent via email.

Error Responses


POST /verification-services/email-verification/complete

Purpose: Completes verification using the received code.

Parameter Type Required Description
email String Yes User’s email
secretCode String Yes Verification code

Success Response

{
  "status": "OK", 
  "isVerified": true,
  "email": "user@email.com",
  // in testMode
  "userId": "user-uuid"
}

Error Responses


Mobile Verification

Mobile numbers must be in E.164 format (+ followed by country code and subscriber number, e.g. +905551234567). Use the PhoneInput component for mobile number inputs on verification pages.

In the registration response, check the mobileVerificationNeeded property in the response root. If it is true, start the mobile verification flow.

After the login process, if you receive a 403 error and the response contains an errCode with the value MobileVerificationNeeded, start the mobile verification flow.

  1. Call the mobile verification start route of the backend (described below) with the user’s email. The backend will send a secret code to the user’s mobile number. If a real texting service is configured, the backend sends the SMS. During development, the backend also returns the secret code to the frontend in the secretCode property.
  2. The secret code in the SMS will be a 6-digit code. Provide an input page so the user can paste this code. Navigate to this input page after starting the verification process. If the secretCode is returned for testing, display it on the input page for easy copy/paste.
  3. When the user submits the code, complete mobile verification using the complete route of the backend (described below) with the user’s email and the secret code.
  4. The start response includes a codeIndex property. Display its value on the input page so the user can match the index shown in the message with the one on the screen.
  5. After a successful mobile verification response, navigate to the login page.

Verification Order If both emailVerificationNeeded and mobileVerificationNeeded are true, handle both verification flows in order. First complete email verification, then mobile verification.

Below are the start and complete routes for mobile verification. These are system routes and therefore are not versioned.

POST /verification-services/mobile-verification/start

Parameter Type Required Description
email String Yes User’s email to locate mobile record

Success Response

{
  "status": "OK", 
  "codeIndex": 1,
  // timeStamp : Milliseconds since Jan 1, 1970, 00:00:00.000 GMT
  "timeStamp": 1784578660000,
  "date": "Mon Jul 20 2026 23:17:40 GMT+0300 (GMT+03:00)",
  // expireTime: in seconds
  "expireTime": 180,
  "verificationType": "byCode",

  // in testMode
  "secretCode": "123456",
  "userId": "user-uuid"
}

⚠️ secretCode is returned only in development.

Errors


POST /verification-services/mobile-verification/complete

Parameter Type Required Description
email String Yes Associated email
secretCode String Yes Code received via SMS

Success Response

{
  "status": "OK", 
  "isVerified": true,
  "mobile": "+1 333 ...",
  // in testMode
  "userId": "user-uuid"
}

Resetting Password

Users can reset their forgotten passwords without a login required, through email verification. To be able to start a password reset flow, users will click on the “Reset Password” link in the login page.

Since there are two verification methods, by email or by mobile, for password reset, when the reset password link is clicked, frontend should ask user if they want to make the verification through email of mobile. According to the users selection the frontend shoudl start the related flow as explaned below step by step.

Password Reset By Email Flow

  1. Call the password reset by email verification start route of the backend (described below) with the user’s email. The backend will send a secret code to the provided email address. The backend can send the email if the architect has configured a real mail service or SMTP server. During development, the backend also returns the secret code to the frontend. You can read this code from the secretCode property of the response.
  2. The secret code in the email will be a 6-digit code. Provide an input page so the user can paste this code into the frontend application. Navigate to this input page after starting the verification process. If the secretCode is sent to the frontend for testing, display it on the input page so the user can copy and paste it.
  3. The start response includes a codeIndex property. Display its value on the input page so the user can match the index in the message with the one on the screen.
  4. The input page should also include a double input area for the user to enter and confirm their new password.
  5. When the user submits the code and the new password, complete the password reset by email using the complete route of the backend (described below) with the user’s email , the secret code and new password.
  6. After a successful verification response, navigate to the login page.

Below are the start and complete routes for password reset by email verification. These are system routes and therefore are not versioned.

POST /verification-services/password-reset-by-email/start

Purpose:
Starts the password reset process by generating and sending a secret verification code.

Request Body

Parameter Type Required Description
email String Yes The email address of the user
{
  "email": "user@example.com"
}

Success Response

Returns secret code details (only in development environment) and confirmation that the verification step has been started.

{
  "userId": "user-uuid",
  "email": "user@example.com",
  "codeIndex": 1,
  "secretCode": "123456", 
  "timeStamp": 1765484354,
  "expireTime": 86400,
  "date": "2024-04-29T10:00:00.000Z",
  "verificationType": "byLink",
}

⚠️ In production, the secret code is only sent via email and not exposed in the API response.

Error Responses


POST /verification-services/password-reset-by-email/complete

Purpose:
Completes the password reset process by validating the secret code and updating the user’s password.

Request Body

Parameter Type Required Description
email String Yes The email address of the user
secretCode String Yes The code received via email
password String Yes The new password the user wants to set
{
  "email": "user@example.com",
  "secretCode": "123456",
  "password": "newSecurePassword123"
}

Success Response

{
  "userId": "user-uuid",
  "email": "user@example.com",
  "isVerified": true
}

Error Responses


Password Reset By Mobile Flow

  1. Call the password reset by mobile verification start route of the backend (described below) with the user’s email. The backend will send a secret code to the user’s mobile number. If a real texting service is configured, the backend sends the SMS. During development, the backend also returns the secret code to the frontend in the secretCode property.
  2. The secret code in the SMS will be a 6-digit code. Provide an input page so the user can paste this code. Navigate to this input page after starting the verification process. If the secretCode is returned for testing, display it on the input page for easy copy/paste.
  3. The start response includes a codeIndex property. Display its value on the input page so the user can match the index in the message with the one on the screen. Also display the half masked mobilenumber that comes in the response, to tell the user that their code is sent to this number.
  4. The input page should also include a double input area for the user to enter and confirm their new password.
  5. When the user submits the code, complete mobile verification using the complete route of the backend (described below) with the user’s email and the secret code.
  6. After a successful mobile verification response, navigate to the login page.

Below are the start and complete routes for password reset by mobile verification. These are system routes and therefore are not versioned.

POST /verification-services/password-reset-by-mobile/start

Purpose:
Initiates the mobile-based password reset by sending a verification code to the user’s mobile.

Request Body

Parameter Type Required Description
email String Yes The email of the user that resets the password
{
  "email": "user@user.com"
}

Success Response

Returns the verification context (code returned only in development):

{
  "status": "OK",
  "codeIndex": 1,
  timeStamp: 133241255,
  "mobile": "+905.....67",
  "secretCode": "123456", 
  "expireTime": 86400,
  "date": "2024-04-29T10:00:00.000Z",
  verificationType: "byLink"
}

⚠️ In production, the secretCode is not included in the response and is only sent via SMS.

Error Responses


POST /verification-services/password-reset-by-mobile/complete

Purpose:
Finalizes the password reset process by validating the received verification code and updating the user’s password.

Request Body

Parameter Type Required Description
email String Yes The email address of the user
secretCode String Yes The code received via SMS
password String Yes The new password to assign
{
  "email": "user@example.com",
  "secretCode": "123456",
  "password": "NewSecurePassword123!"
}

Success Response

{
  "userId": "user-uuid",
  "isVerified": true
}

Two-Factor Authentication (2FA)

This project has email two-factor authentication enabled. 2FA is different from email/mobile verification: verification proves ownership during registration (one-time), while 2FA runs on every login as an additional security layer.

How 2FA Works After Login

When a user logs in successfully, the login response includes accessToken, userId, sessionId, and all session data. However, when 2FA is active, the response also contains one or both of these flags:

When any of these flags are true, the session is NOT fully authorized. The accessToken is valid only for calling the 2FA verification endpoints. All other protected API calls will return 403 Forbidden with error code EmailTwoFactorNeeded or MobileTwoFactorNeeded until 2FA is completed.

2FA Frontend Flow

  1. After a successful login, check the response for sessionNeedsEmail2FA or sessionNeedsMobile2FA.
  2. If either is true, do not treat the user as authenticated. Store the accessToken, userId, and sessionId temporarily.
  3. Navigate the user to a 2FA verification page.
  4. On the 2FA page, immediately call the 2FA start endpoint (described below) with the userId and sessionId. This triggers sending the verification code to the user’s email.
  5. Display a 6-digit code input. If the response contains secretCode (test/development mode), display it on the page so the user can copy and paste it.
  6. The start response includes a codeIndex property. Display its value on the page so the user can match the index in the message with the one on the screen.
  7. When the user submits the code, call the 2FA complete endpoint with userId, sessionId, and secretCode.
  8. On success, the complete endpoint returns the updated session object with the 2FA flag cleared. Now set the user as fully authenticated and navigate to the main application page.
  9. Provide a “Resend Code” button with a 60-second cooldown to prevent spam.
  10. Provide a “Cancel” option that discards the partial session and returns the user to the login page.

Email 2FA Endpoints

POST /verification-services/email-2factor-verification/start

Purpose: Starts email-based 2FA by generating and sending a verification code to the user’s email.

Parameter Type Required Description
userId String Yes The user’s ID
sessionId String Yes The current session ID

Example Request

{
  "userId": "user-uuid",
  "sessionId": "session-uuid"
}

Success Response

{
  "status": "OK",
  "sessionId": "session-uuid",
  "userId": "user-uuid",
  "codeIndex": 1,
  "timeStamp": 1784578660000,
  "date": "Mon Jul 20 2026 23:17:40 GMT+0300",
  "expireTime": 86400,
  "verificationType": "byCode",

  // in testMode only
  "secretCode": "123456"
}

⚠️ In production, secretCode is not returned — it is only sent via email.

Error Responses


POST /verification-services/email-2factor-verification/complete

Purpose: Completes email 2FA by validating the code and clearing the session 2FA flag.

Parameter Type Required Description
userId String Yes The user’s ID
sessionId String Yes The session ID
secretCode String Yes Verification code from email

Success Response

Returns the updated session with sessionNeedsEmail2FA: false:

{
  "sessionId": "session-uuid",
  "userId": "user-uuid",
  "email": "user@example.com",
  "fullname": "John Doe",
  "roleId": "user",
  "sessionNeedsEmail2FA": false,
  "accessToken": "jwt-token",
  "...": "..."
}

Error Responses


Important 2FA Notes

** Please dont forget to arrange the code to be able to navigate to the verification pages both after registrations and login attempts if verification is needed.**

After this prompt, the user may give you new instructions to update your first output or provide subsequent prompts about the project.