Skip to main content
The Storefront API uses OTP-based authentication. Customers receive a 4-digit verification code via SMS or email, verify it, and receive a Bearer token for authenticated requests.

Flow Overview

  1. Start — Send phone number or email to receive an OTP code
  2. Verify — Submit the OTP code to verify identity
  3. Complete — (New customers only) Provide name and email to finish registration

POST /auth/start

Start an authentication session. Auto-detects the type based on provided fields.

Authentication

None required (guest endpoint).

Request

Headers

HeaderValueRequired
Content-Typeapplication/jsonYes

Body Parameters

ParameterTypeRequiredDescription
country_codenumericYes (phone auth)Country dial code (1-999, e.g., 966)
phonestringYes (phone auth)Phone number without country code (digits only)
emailstringYes (email auth)Customer email address
Provide either country_code + phone for phone authentication, or email for email authentication. The API auto-detects which flow to use.

Example Request

curl -X POST "https://front.rmz.gg/api/auth/start" \
  -H "Content-Type: application/json" \
  -d '{
    "country_code": "966",
    "phone": "501234567"
  }'

Response

Success (200)

{
  "success": true,
  "data": {
    "session_token": "auth_abc123xyz"
  },
  "message": "Verification code sent successfully"
}

Error Responses

StatusMessageDescription
422(validation errors)Missing or invalid phone/email fields
429Too many authentication attempts today. Please try again tomorrow50 sessions/day per IP exceeded
429Too many authentication attempts for this phone number today10 sessions/day per phone number exceeded
500Store not found in contextStore could not be resolved

POST /auth/phone/start

Dedicated phone authentication endpoint. Behaves identically to POST /auth/start with phone parameters but enforces phone-specific validation.

Body Parameters

ParameterTypeRequiredDescription
country_codenumericYesCountry dial code (1-999)
phonestringYesPhone number (digits only)

POST /auth/initiate

Legacy authentication endpoint. Accepts a type field and nested data object instead of top-level fields.

Authentication

None required (guest endpoint).

Body Parameters

ParameterTypeRequiredDescription
typestringYesAuthentication type. Currently only phone is supported
data.countrystringYes (phone)Country dial code (must be a supported Arab country code)
data.phonestringYes (phone)Phone number (6-12 digits)
data.emailstringYes (email)Customer email address

Response

Same as POST /auth/start.
This is a legacy endpoint maintained for backward compatibility. New integrations should use POST /auth/start instead.

POST /auth/verify

Verify the OTP code sent to the customer’s phone or email.

Authentication

None required (guest endpoint).

Request

Headers

HeaderValueRequired
Content-Typeapplication/jsonYes

Body Parameters

ParameterTypeRequiredDescription
session_tokenstringNoSession token from the start step
codeintegerYesThe 4-digit OTP code
otpintegerNoAlias for code (backward compatibility)

Example Request

curl -X POST "https://front.rmz.gg/api/auth/verify" \
  -H "Content-Type: application/json" \
  -d '{
    "session_token": "auth_abc123xyz",
    "code": 1234
  }'

Response

Existing Customer (200)

When the customer already exists in this store:
{
  "success": true,
  "data": {
    "type": "authenticated",
    "token": "1|abc123xyz...",
    "cart_token": "cart_xyz789",
    "customer": {
      "id": 123,
      "first_name": "Ahmed",
      "last_name": "Ali",
      "email": "ahmed@example.com",
      "phone": "501234567",
      "country_code": "966"
    }
  },
  "message": "Authentication successful"
}

Customer From Another Store (200)

When the customer exists in another store but not in this one, a new customer record is automatically created for this store:
{
  "success": true,
  "data": {
    "type": "new_customer",
    "token": "1|abc123xyz...",
    "cart_token": "cart_xyz789",
    "customer": {
      "id": 456,
      "first_name": "Ahmed",
      "last_name": "Ali",
      "email": "ahmed@example.com",
      "phone": "501234567",
      "country_code": "966"
    }
  },
  "message": "Authentication successful"
}
The type field can be either "authenticated" (existing customer in this store) or "new_customer" (auto-created from another store). Both cases return a token and the customer can proceed immediately.

New Customer (200)

When the phone/email is not registered in any store, the response indicates registration is required:
{
  "success": true,
  "data": {
    "type": "new",
    "requires_registration": true,
    "session_token": "auth_abc123xyz"
  },
  "message": "Please complete your registration"
}
When requires_registration is true, you must call POST /auth/complete to finish creating the customer account.

Error Responses

StatusMessageDescription
400Please restart the authentication processInvalid or missing session
400Verification code expired. Please restart the processSession has expired
400Too many failed attempts. Please restart the processMax verification attempts reached
400Invalid verification codeWrong OTP code
429Too many verification attempts. Please wait before trying againRate limit exceeded (5 attempts/min per IP)
429Please wait seconds before trying againProgressive cooldown active

POST /auth/phone/verify

Dedicated phone verification endpoint. Behaves identically to POST /auth/verify.

POST /auth/resend

Resend the OTP code for an active session.

Authentication

None required (guest endpoint).

Request

Body Parameters

ParameterTypeRequiredDescription
session_tokenstringYesSession token from the start step

Example Request

curl -X POST "https://front.rmz.gg/api/auth/resend" \
  -H "Content-Type: application/json" \
  -d '{
    "session_token": "auth_abc123xyz"
  }'

Response

Success (200)

{
  "success": true,
  "data": {
    "session_token": "auth_abc123xyz"
  },
  "message": "Verification code sent successfully"
}

Error Responses

StatusMessageDescription
400Invalid session. Please restart the authentication processSession token not found
400Session expired. Please restart the authentication processSession has expired
429Please wait 30 seconds before requesting a new codeMust wait 30 seconds between resends
429Too many resend attempts. Please wait before trying again3 resends per 10 minutes exceeded

POST /auth/phone/resend

Dedicated phone resend endpoint. Behaves identically to POST /auth/resend.

POST /auth/complete

Complete registration for new customers after OTP verification.

Authentication

None required (guest endpoint). Requires a verified session token.

Request

Body Parameters

ParameterTypeRequiredDescription
session_tokenstringYesVerified session token
emailstringYesCustomer email (must be unique per store)
firstNamestringYesCustomer first name
lastNamestringYesCustomer last name

Example Request

curl -X POST "https://front.rmz.gg/api/auth/complete" \
  -H "Content-Type: application/json" \
  -d '{
    "session_token": "auth_abc123xyz",
    "email": "ahmed@example.com",
    "firstName": "Ahmed",
    "lastName": "Ali"
  }'

Response

Success (200)

{
  "success": true,
  "data": {
    "type": "registered",
    "token": "1|abc123xyz...",
    "customer": {
      "id": 456,
      "first_name": "Ahmed",
      "last_name": "Ali",
      "email": "ahmed@example.com",
      "phone": "501234567",
      "country_code": "966"
    }
  },
  "message": "Account created and authenticated successfully"
}

Error Responses

StatusMessageDescription
400Please restart the authentication processSession not found, not verified, or not eligible for registration
400Session expired. Please restart the processSession has expired
400Customer already exists. Please login with existing credentialsCustomer record already exists for this store
422(validation errors)Email already in use in this store, or missing required fields

Rate Limits Summary

ActionLimitWindow
Start authentication50 per IP24 hours
Phone-specific start10 per phone number24 hours
Verify OTP5 per IP1 minute
Resend OTP3 per identifier10 minutes
Resend cooldown1 per session30 seconds

Session Expiry

OTP sessions expire after 5 minutes. Expired sessions are automatically cleaned up. If a session expires, the customer must restart the authentication flow from POST /auth/start.