Customer Authentication API
The Customer Auth API provides authentication flows for end-user customers. It supports multiple authentication methods including password, OTP, OAuth, and Shopify integration.
Authentication Methods
| Method | Description | Use Case |
|---|---|---|
| Password | Email + password | Traditional login |
| OTP | One-time password via email | Passwordless login |
| OAuth/OIDC | External providers | Social login, SSO |
| Shopify Multipass | Shopify Plus SSO | Headless Shopify |
Standard Authentication
customerLogin
Login with email and password.
mutation CustomerLogin($email: String!, $password: String!) {
customerLogin(email: $email, password: $password) {
success
accessToken
refreshToken
user {
id
email
userType
}
}
}Response:
{
"data": {
"customerLogin": {
"success": true,
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"user": {
"id": "user_123",
"email": "customer@example.com",
"userType": "CUSTOMER"
}
}
}
}customerRegister
Register a new customer account.
mutation CustomerRegister($email: String!, $password: String!) {
customerRegister(email: $email, password: $password) {
success
accessToken
refreshToken
user {
id
email
}
emailVerificationRequired
}
}customerLogout
Logout the current customer.
mutation CustomerLogout {
customerLogout {
success
message
}
}OTP Authentication
Request OTP
mutation RequestOTP($email: String!) {
customerRequestOTP(email: $email) {
success
expiresAt
message
}
}Login with OTP
mutation LoginWithOTP($email: String!, $otp: String!) {
customerLoginOTP(email: $email, otp: $otp) {
success
accessToken
refreshToken
user {
id
email
}
}
}Password Management
Request Password Reset
mutation RequestReset($email: String!) {
customerRequestPasswordReset(email: $email) {
success
message
}
}Reset Password
mutation ResetPassword($token: String!, $newPassword: String!) {
customerResetPassword(token: $token, newPassword: $newPassword) {
success
message
}
}Update Password (Authenticated)
mutation UpdatePassword($currentPassword: String!, $newPassword: String!) {
customerUpdatePassword(
currentPassword: $currentPassword
newPassword: $newPassword
) {
success
message
}
}Token Management
Refresh Token
mutation RefreshToken($refreshToken: String!) {
customerRefreshToken(refreshToken: $refreshToken) {
success
accessToken
refreshToken
}
}Get Current User
query CurrentUser {
currentUser {
id
email
emailVerified
status
userType
createdAt
}
}Email Verification
Verify Email
mutation VerifyEmail($token: String!) {
customerVerifyEmail(token: $token) {
success
user {
id
emailVerified
}
message
}
}Resend Verification Email
mutation ResendVerification {
customerResendVerificationEmail {
success
message
}
}Auth Provider Integration
For projects with external auth providers configured (OAuth, OIDC, Shopify, etc.).
List Available Providers
query ListProviders {
authProviders {
id
key
name
type
enabled
isDefault
priority
}
}Login with Provider
The unified customerLoginWithProvider mutation handles all provider types including OAuth (Google, Auth0), OIDC, and Shopify (Multipass/OTP).
mutation ProviderLogin($providerKey: String, $email: String!) {
customerLoginWithProvider(input: {
providerKey: $providerKey
email: $email
returnTo: "https://mysite.com/callback"
}) {
method
providerId
providerKey
# For OAuth - redirect to this URL
redirectUrl
state
# For Multipass/direct auth - tokens returned immediately
accessToken
refreshToken
shopifyAccessToken # Shopify-specific
shopifyTokenExpiresAt # Shopify-specific
# For OTP - confirmation
otpSent
expiresAt
}
}Handle OAuth Callback
mutation ProviderCallback($code: String!, $state: String!) {
customerProviderCallback(input: {
providerKey: "google"
code: $code
state: $state
}) {
accessToken
refreshToken
user {
id
email
}
isNewCustomer
}
}Verify Provider OTP
Used for OTP-based providers including Shopify (non-Plus stores).
mutation VerifyProviderOTP($email: String!, $otp: String!) {
customerProviderVerifyOTP(input: {
providerKey: "shopify"
email: $email
otp: $otp
}) {
accessToken
refreshToken
user { id email }
isNewCustomer
}
}Shopify Customer Authentication
Shopify authentication is handled through the unified auth providers system using providerKey: "shopify".
Shopify Login Flow
# Step 1: Initiate login
mutation ShopifyLogin($email: String!) {
customerLoginWithProvider(input: {
providerKey: "shopify"
email: $email
}) {
method # MULTIPASS or OTP
# For Multipass (Shopify Plus stores) - direct auth
accessToken
refreshToken
shopifyAccessToken
shopifyTokenExpiresAt
# For OTP (non-Plus stores) - requires verification
otpSent
expiresAt
}
}Shopify OTP Verification
For non-Plus stores that use OTP:
# Step 2: Verify OTP (only if method was OTP)
mutation ShopifyVerifyOTP($email: String!, $otp: String!) {
customerProviderVerifyOTP(input: {
providerKey: "shopify"
email: $email
otp: $otp
}) {
accessToken
refreshToken
user { id email }
isNewCustomer
}
}Refresh Shopify Token
Shopify Customer Access Tokens expire in ~1 hour. Refresh before expiry:
mutation RefreshShopifyToken($currentToken: String!, $shopId: String!) {
refreshShopifyCustomerToken(
currentToken: $currentToken
shopId: $shopId
) {
accessToken
expiresAt
}
}Configuration
Get Auth Configuration
query AuthConfig {
authConfig {
authMethods
publicRegistrationEnabled
passwordPolicy {
minLength
requireUppercase
requireLowercase
requireNumbers
requireSpecialChars
}
}
}Response Types
LoginResponse
type LoginResponse {
success: Boolean!
accessToken: String
refreshToken: String
user: User
}User
type User {
id: ID!
email: String!
emailVerified: Boolean!
status: UserStatus
userType: UserType!
tenantId: ID
projectId: ID
createdAt: DateTime!
updatedAt: DateTime!
}
enum UserStatus {
ACTIVE
INACTIVE
SUSPENDED
}
enum UserType {
CUSTOMER
ADMIN
}Using Access Tokens
Include the access token in subsequent requests:
curl -X POST https://api.foir.io/graphql/public \
-H "Content-Type: application/json" \
-H "x-api-key: pk_live_..." \
-H "Authorization: Bearer eyJhbGc..." \
-d '{"query": "{ currentUser { id email } }"}'Example: Complete Login Flow
// 1. Check auth config
const { data: config } = await client.query({ query: AUTH_CONFIG });
// 2. Login
const { data: login } = await client.mutate({
mutation: CUSTOMER_LOGIN,
variables: { email, password }
});
if (login.customerLogin.success) {
// 3. Store tokens
localStorage.setItem('accessToken', login.customerLogin.accessToken);
localStorage.setItem('refreshToken', login.customerLogin.refreshToken);
// 4. Get user profile
const { data: user } = await client.query({
query: CURRENT_USER,
context: {
headers: {
Authorization: `Bearer ${login.customerLogin.accessToken}`
}
}
});
}Example: Token Refresh
async function refreshTokenIfNeeded() {
const refreshToken = localStorage.getItem('refreshToken');
const { data } = await client.mutate({
mutation: REFRESH_TOKEN,
variables: { refreshToken }
});
if (data.customerRefreshToken.success) {
localStorage.setItem('accessToken', data.customerRefreshToken.accessToken);
localStorage.setItem('refreshToken', data.customerRefreshToken.refreshToken);
}
}