FleetbaseFleetbase

Customer Authentication

Configure customer authentication — SMS code, email/password, Apple, Google, and Facebook sign-in. The full registration, verification, and login flow with API examples, and the limits on endpoints that send a text.

Customer Authentication

Storefront provides a complete authentication system for your customers. On successful authentication, the API returns a Sanctum personal access token. Your customer-facing app stores this token and includes it on every authenticated request via the Customer-Token header (the storefront key still goes in Authorization: Bearer).

Storefront app — customer login screen with phone number and one-time code

GET /storefront/v1/customers/me
Authorization: Bearer store_your_store_key
Customer-Token: 1|VlKK7lZ...

Authentication Methods

SMS Code (default)

The most common method for on-demand delivery apps. No password required — a one-time code is sent to the customer's phone.

Email / Phone + Password

Traditional credentials login. The login endpoint accepts an identity field that can be either an email or a phone number, plus a password.

Social Sign-In

Storefront supports:

  • Apple Sign-In — required by Apple for iOS apps that offer other social logins
  • Google Sign-In
  • Facebook Sign-In

Each social provider has its own login endpoint and required parameters — see Social Login below.

This is social sign-in for Storefront customers. For your own team signing in to the Fleetbase console with Google, Microsoft, GitHub, or Apple, see OAuth Sign-in.

Registration Flow

Registration is a two-step flow. The customer first requests a verification code, then submits their details along with the code.

1. Request a verification code

POST /storefront/v1/customers/request-creation-code
Authorization: Bearer store_your_store_key

{
  "mode": "sms",
  "identity": "+15551234567"
}

mode is sms or email (the default is email); identity is the phone number or email address the code goes to. The code expires after ten minutes and can be used once.

The request is refused with 422 when an account already exists for the identity (the response says so; send the customer to sign in instead) or when the phone number is invalid or cannot receive a text message. Asking again for the same identity inside a minute answers ok without sending a second message, so a retry button is safe to offer.

2. Create the customer

POST /storefront/v1/customers
Authorization: Bearer store_your_store_key

{
  "name": "Jane Doe",
  "email": "customer@example.com",
  "phone": "+15551234567",
  "password": "securepassword",
  "code": "123456"
}

Phone numbers must include the international prefix (e.g. +1, +44). The API normalizes the value and prepends + automatically if missing.

A wrong code counts against the one that was sent; after five wrong guesses the code locks and a new one must be requested. After ten wrong codes for the same identity, whatever the address they came from, the identity is locked out of code checks for fifteen minutes and the endpoint answers 429.

Login

SMS Code Login

POST /storefront/v1/customers/login-with-sms
Authorization: Bearer store_your_store_key

{
  "phone": "+15551234567"
}

Verify the code that was sent:

POST /storefront/v1/customers/verify-code
Authorization: Bearer store_your_store_key

{
  "identity": "+15551234567",
  "code": "123456"
}

The login response carries "method": "sms". When the text cannot be sent (the store has no SMS provider configured, or the SMS Guard refused it) and the customer has an email address on file, the code is emailed instead and the response carries "method": "email". Verify it with the same verify-code call.

Email / Phone + Password Login

POST /storefront/v1/customers/login
Authorization: Bearer store_your_store_key

{
  "identity": "customer@example.com",
  "password": "securepassword"
}

The identity field can be either an email address or a phone number.

Limits on endpoints that send a text

Every endpoint that sends an SMS (request-creation-code, login-with-sms, request-phone-verification, account-closure) is limited to 5 requests a minute per storefront key and client address, on top of the general storefront throttle, and every message passes the platform's SMS Guard. Handle these statuses in your app:

StatusMeaningWhat to do
422The number is invalid or cannot receive a text, or an account already exists for the identity.Show the message; do not retry.
429Too many requests, a cooldown on that number, or the store's message budget.Wait for the Retry-After header before retrying.
423Text messages are paused for this store.Offer email login or password login; retry later.

Response

All login endpoints return the same structure on success:

{
  "token": "1|VlKK7lZ...",
  "customer": {
    "id": "customer_abc123",
    "name": "Jane Doe",
    "email": "customer@example.com",
    "phone": "+15551234567"
  }
}

Store the token securely (e.g. iOS Keychain, Android Keystore, or expo-secure-store). Pass it on every authenticated request:

Customer-Token: 1|VlKK7lZ...

Social Login

Apple

POST /storefront/v1/customers/login-with-apple
Authorization: Bearer store_your_store_key

{
  "identityToken": "...",
  "authorizationCode": "...",
  "appleUserId": "...",
  "name": "Jane Doe"
}

Apple does not always return name/email — pass them along the first time, since they're omitted on subsequent sign-ins.

Google

POST /storefront/v1/customers/login-with-google
Authorization: Bearer store_your_store_key

{
  "idToken": "...",
  "clientId": "..."
}

Facebook

POST /storefront/v1/customers/login-with-facebook
Authorization: Bearer store_your_store_key

{
  "facebookUserId": "...",
  "email": "customer@example.com",
  "name": "Jane Doe"
}

Phone Verification (post-registration)

To verify a customer's phone after they've signed up (e.g. when they update it):

POST /storefront/v1/customers/request-phone-verification
POST /storefront/v1/customers/verify-phone-number

The first call takes phone and texts the code to that number. It goes to the new number, not the one on file, so it also works for a customer who has no number yet. It answers 422 when the number is invalid, cannot receive a text, or already belongs to another account. The second call takes the code and only then saves the number on the customer. The code expires after ten minutes and verifies once. This needs fleetbase/core-api 1.6.70 or later; earlier versions texted the number on file.

Account Closure

For App Store and Play Store compliance, expose an in-app account closure flow:

POST /storefront/v1/customers/account-closure
POST /storefront/v1/customers/confirm-account-closure

The first endpoint sends a confirmation code to the customer's phone, or to their email when the text cannot be sent; the second takes the code and closes the account. The code expires after ten minutes and verifies once.

Device Registration (push)

For push notifications to reach the customer, register their device token after authentication:

POST /storefront/v1/customers/register-device
Authorization: Bearer store_your_store_key
Customer-Token: 1|VlKK7lZ...

{
  "platform": "ios",
  "token": "<APNs or FCM device token>"
}

See Notifications for setting up the underlying APNs / FCM channels.

Stripe Helpers

If you use Stripe, two endpoints support saved-card / PaymentSheet flows:

POST /storefront/v1/customers/stripe-ephemeral-key
POST /storefront/v1/customers/stripe-setup-intent

Realtime Socket Token

To receive realtime updates for their own orders, a signed-in customer mints a short-lived socket token:

POST /storefront/v1/customers/socket-token
Authorization: Bearer store_your_store_key
Customer-Token: 1|VlKK7lZ...
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 900,
  "expires_at": "2026-01-01T12:15:00+00:00"
}

Connect to the socket server with socketcluster-client, present the token in the handshake (an in-memory authEngine) or with socket.authenticate(token), and refresh it about 60 seconds before expires_in elapses. The token only allows the customer's own channels — their orders (order.{order id}) and the driver and vehicle serving an active order. Keep it in memory only. Instances without socket authentication answer 404; connect without a token in that case. In @fleetbase/storefront the call is customer.socketToken().

Token Sessions

Tokens issued via these endpoints are Laravel Sanctum personal access tokens. Handle 401 Unauthorized by re-authenticating. Tokens can be revoked server-side by an admin.

If you are using the Storefront App, sign-in is already built in: phone number and texted code, plus Sign in with Apple and Sign in with Google once they are set up. The app doesn't offer Facebook sign-in; the endpoint above remains for your own clients. See Storefront App → Sign-in for the Apple and Google setup.

Customer Authentication | Fleetbase