Branding, sign-in methods and feature availability
Read branding, enabled sign-in methods, minimum app versions and feature availability before displaying the sign-in screen. A public app ID is required; a customer token is not. Configured phone sign-in is advertised only when the selected phone verification provider is available or this active app has an explicit test-number allow-list with test OTP enabled. A globally advertised phone option does not make every number a test number: without usable SMS, a non-listed number can still return 422 method_not_enabled.
cURL request
curl --request GET "$BASE_URL/config" \
--header 'Accept: application/json' \
--header 'X-App-Id: YOUR_APP_ID'Responses
200 Success
Success
application/json · Schema-generated illustration; optional fields and values vary
{
"business": {
"name": "string",
"currency": "string",
"locale": "string",
"timezone": "string"
},
"app": {
"name": "string",
"sign_up_methods": [
"phone"
],
"min_app_version": {
"ios": "string",
"android": "string"
},
"customer_experience_mode": "app_only"
},
"card": {
"title": "string",
"logo_url": "string",
"color": "string",
"points_label": "string",
"redemption_model": "string",
"earn_rule_label": "string"
},
"whatsapp_number": "string",
"google_wallet": false,
"apple_wallet": false,
"input_profile": {
"country_code": "string",
"country_name": "string",
"dialing_code": "string",
"address_format": "string",
"fields": {
"phone": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
},
"city": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
},
"area": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
},
"province": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
},
"postal_code": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
},
"address": {
"label": "string",
"placeholder": "string",
"suggestions": [
"string"
]
}
}
},
"phone_otp": {
"default_country": "string",
"countries": [
{
"code": "GB",
"name": "United Kingdom",
"dialing_code": "+44",
"flag": "🇬🇧"
}
]
},
"anonymous": {
"enabled": false,
"remember_days": 0
},
"loyalty": {
"available": false
},
"legal": {
"terms_url": "https://example.com/resource",
"privacy_url": "https://example.com/resource"
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
businessoptional; see conditions | object | Business identity and regional settings for the resolved tenant. | — |
business.nameoptional; see conditions | string | Display name of the object represented here; do not use it as a stable identifier. | — |
business.currencyoptional; see conditions | string | ISO 4217 currency code, for example GBP or AED. Monetary amounts are expressed in its minor units. | — |
business.localeoptional; see conditions | string | Language/region code such as en_GB; determines localized presentation. | — |
business.timezoneoptional; see conditions | string | IANA timezone such as Europe/London or Asia/Dubai, used for business-local rules and schedules. | — |
appoptional; see conditions | object | Customer app display settings and supported sign-in policy. | — |
app.nameoptional; see conditions | string | Display name of the object represented here; do not use it as a stable identifier. | — |
app.sign_up_methodsoptional; see conditions | array<string> | Enabled methods for both sign-in and sign-up. Show only these choices, including for returning customers. Configured phone sign-in is advertised only when a usable SMS verification account is available or this active app has an explicit test-number allow-list with test OTP enabled. A globally advertised phone option does not make every number a test number: without usable SMS, a non-listed number can still return 422 method_not_enabled. | — |
app.min_app_versionoptional; see conditions | object | Minimum supported app version by platform, or the version required by an upgrade error. | — |
app.min_app_version.iosoptional; see conditions | string | Minimum supported iOS app version as major.minor.patch; absent when no minimum is configured. | — |
app.min_app_version.androidoptional; see conditions | string | Minimum supported Android app version as major.minor.patch; absent when no minimum is configured. | — |
app.customer_experience_modeoptional; see conditions | string | Platform-managed customer experience mode. Native customer requests are refused with 403 customer_channel_unavailable for app_free_only. Staff access and installed Wallet validity are independent. | Allowed: app_only, app_free_only, hybrid |
cardoptional; see conditions | object | null | Loyalty card branding or milestone progress, depending on this response. | — |
card.titleoptional; see conditions | string | Customer-facing title printed on the loyalty card. | — |
card.logo_urloptional; see conditions | string | null | URL of the business loyalty card logo, when configured. | — |
card.coloroptional; see conditions | string | Configured loyalty card brand color, for example #6b3e26. | — |
card.points_labeloptional; see conditions | string | Business-specific display label for points, such as points or beans. | — |
card.redemption_modeloptional; see conditions | string | Loyalty program model: catalogue exchanges points for rewards; milestones unlocks rewards through card progress. | — |
card.earn_rule_labeloptional; see conditions | string | null | Short text set by the business describing how points are earned. Hide the line when null. | Max length: 60 |
whatsapp_numberoptional; see conditions | string | null | Business WhatsApp number in international format, or null when none is configured. | — |
google_walletoptional; see conditions | boolean | Whether Google Wallet is available for this business/customer. | — |
apple_walletoptional; see conditions | boolean | Whether Apple Wallet pass downloads are configured for this business. | — |
input_profileoptional; see conditions | object | Country-specific presentation hints resolved from the business country. Apply these labels and placeholders without treating phone hints as validation masks. International phone numbers remain allowed. | — |
input_profile.country_coderequired in parent object | string | null | ISO 3166-1 alpha-2 code of the business country, or null when not configured. | — |
input_profile.country_namerequired in parent object | string | null | Display name of the business country, or null when not configured. | — |
input_profile.dialing_coderequired in parent object | string | null | Default international dialing prefix used to interpret local phone input; international numbers remain allowed. | — |
input_profile.address_formatrequired in parent object | string | null | Configured country address-format hint, or null when not configured. | — |
input_profile.fieldsrequired in parent object | object | Localized field labels, example placeholders and optional non-exhaustive suggestions. | — |
input_profile.fields.phonerequired in parent object | object | Presentation hints for the phone field; these do not impose additional validation rules. | — |
input_profile.fields.phone.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.phone.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.phone.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
input_profile.fields.cityrequired in parent object | object | Presentation hints for the city field; these do not impose additional validation rules. | — |
input_profile.fields.city.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.city.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.city.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
input_profile.fields.arearequired in parent object | object | Presentation hints for the area field; these do not impose additional validation rules. | — |
input_profile.fields.area.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.area.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.area.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
input_profile.fields.provincerequired in parent object | object | Presentation hints for the province field; these do not impose additional validation rules. | — |
input_profile.fields.province.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.province.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.province.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
input_profile.fields.postal_coderequired in parent object | object | Presentation hints for the postal code field; these do not impose additional validation rules. | — |
input_profile.fields.postal_code.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.postal_code.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.postal_code.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
input_profile.fields.addressrequired in parent object | object | Presentation hints for the address field; these do not impose additional validation rules. | — |
input_profile.fields.address.labelrequired in parent object | string | Localized display label for this input. | — |
input_profile.fields.address.placeholderrequired in parent object | string | Example input hint; not a validation mask or a required value. | — |
input_profile.fields.address.suggestionsoptional; see conditions | array<string> | Optional non-exhaustive suggestions; free text remains valid. | — |
phone_otpoptional; see conditions | object | Countries this business can send phone verification codes to. Super admins switch them on per business from a reference list of every country; the business's own country is on by default. Build the phone country-code picker from these only; the server refuses other numbers with 422 country_not_allowed. An empty list means phone codes are unavailable. | — |
phone_otp.default_countryrequired in parent object | string | null | ISO 3166-1 alpha-2 code to preselect: the business country when allowed, else the first listed; null when the list is empty. | — |
phone_otp.countriesrequired in parent object | array<object> | Business country first, then by name. | — |
phone_otp.countries[].coderequired in parent object | string | ISO 3166-1 alpha-2 code. | —Example: GB |
phone_otp.countries[].namerequired in parent object | string | Country name in English. | —Example: United Kingdom |
phone_otp.countries[].dialing_coderequired in parent object | string | International dialing prefix with a leading +. | —Example: +44 |
phone_otp.countries[].flagrequired in parent object | string | Flag emoji. | —Example: 🇬🇧 |
anonymousoptional; see conditions | object | Additional optional browser enrollment policy. Native anonymous enrollment is not supported. | — |
anonymous.enabledoptional; see conditions | boolean | Whether the business currently accepts anonymous browser joins. | — |
anonymous.remember_daysoptional; see conditions | integer | Absolute lifetime of anonymous private-browser authority; browser storage may be cleared earlier. | — |
loyaltyoptional; see conditions | object | null | Current rewards programme availability; null when loyalty is not enabled. | — |
loyalty.availableoptional; see conditions | boolean | False while the store has paused the rewards programme; show the paused screen. Null object means loyalty is not enabled. | — |
legaloptional; see conditions | object | Public Terms of Use and Privacy Policy URLs for this business. | — |
legal.terms_urloptional; see conditions | string | Public HTTPS Terms of Use page. Always present: the business's hosted page, or its own website when the business chose that. | Format: uri |
legal.privacy_urloptional; see conditions | string | Public HTTPS Privacy Policy page. Always present: the business's hosted page, or its own website when the business chose that. | Format: uri |
401 Authentication required
Authentication required — Sign in again when the token is expired or revoked. Check X-App-Id for customer requests.
application/json · Illustrative example
{
"error": {
"code": "unauthenticated",
"message": "Authentication required."
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
403 Customer access denied. For an otherwise valid customer token or a successfully verified sign-in code, account_unavailable with reason suspended means the account is on hold. Show the suspension screen and stop automatic retries. Invalid/expired/revoked/wrong-business tokens remain 401; auth/start does not reveal account state. Other 403 codes retain their feature/access meanings.
Customer access denied. For an otherwise valid customer token or a successfully verified sign-in code, account_unavailable with reason suspended means the account is on hold. Show the suspension screen and stop automatic retries. Invalid/expired/revoked/wrong-business tokens remain 401; auth/start does not reveal account state. Other 403 codes retain their feature/access meanings.
application/json · Illustrative example
Feature or API access is unavailable
{
"error": {
"code": "api_access_unavailable",
"message": "API access is unavailable."
}
}Customer account is suspended
{
"error": {
"code": "account_unavailable",
"reason": "suspended",
"message": "This account is suspended. Please contact the business."
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
404 Not found
Not found — Check the public identifier and business context. Resources belonging to another tenant are not accessible.
application/json · Illustrative example
{
"error": {
"code": "not_found",
"message": "Not found."
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
409 Conflict
Conflict — Reuse a key only for an identical operation. For voucher_already_used, refresh reward status instead of redeeming again.
application/json · Illustrative example
{
"error": {
"code": "idempotency_conflict",
"message": "This key was used with different request details."
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
422 Validation or domain refusal
Validation or domain refusal — Correct the fields or handle the domain refusal identified by error.code. Do not retry an unchanged invalid request.
application/json · Illustrative example
{
"error": {
"code": "invalid",
"message": "Some fields are invalid.",
"fields": {
"field_name": [
"A validation message."
]
}
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
426 App upgrade required
App upgrade required — Use the supported minimum app version reported by configuration.
application/json · Illustrative example
{
"error": {
"code": "upgrade_required",
"message": "Please update the app."
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |
429 Rate limited; Retry-After header
Rate limited; Retry-After header — Wait for the Retry-After header before retrying; retain the same operation key for a mutation.
Retry-After — Seconds until a retry is allowed
application/json · Illustrative example
{
"error": {
"code": "rate_limited",
"message": "Too many requests; slow down.",
"retry_after": 60
}
}Response schema
| Field | Type | Description | Constraints & example |
|---|---|---|---|
errorrequired in parent object | object | Application error envelope. Use code for application behavior and message for display. | — |
error.coderequired in parent object | string | Stable application error code such as invalid or rate_limited. Use this value for application decisions, not message text. | —Example: invalid |
error.messagerequired in parent object | string | Human-readable message; do not parse its wording to decide application behavior. | — |
error.fieldsoptional; see conditions | object | Validation messages keyed by request field name, including dotted paths for nested fields. | — |
error.retry_afteroptional; see conditions | integer | Seconds to wait before retrying after a rate limit. Also honor the Retry-After response header. | — |
error.min_app_versionoptional; see conditions | string | Minimum supported app version by platform, or the version required by an upgrade error. | — |
error.attempts_leftoptional; see conditions | integer | Only on invalid_code: wrong codes still allowed before too_many_attempts. | — |
error.reasonoptional; see conditions | string | Optional machine-readable account refusal reason. suspended is returned with account_unavailable after valid customer token authentication or successful sign-in code verification. Never infer suspension from an unauthenticated request. | —Example: suspended |