Chain Resource
The Chain resource represents a top-level retail organisation or brand tenant in the Spaaza platform. Each chain has properties for configuration settings, contact details, and operational preferences.
Contents
Introduction
A Chain in Spaaza represents a retail organisation that operates one or more physical or online stores (Businesses). The Chain resource provides comprehensive information about the organisation including:
- Basic information (name, contact details)
- Currency and language settings
- Authentication and JWT configuration
- Voucher and basket calculation behaviour
- IP address whitelisting configuration
- Associated allowed IP ranges
The Chain resource is a singular resource — it is identified by the X-Spaaza-Chain-ID header and does not support plural listing. It supports GET for retrieval and PUT/PATCH for updates (with super-user access).
Available Paths
Single Resource Operations
GET /resources/chain- Retrieve the chain identified by theX-Spaaza-Chain-IDheaderGET /resources/chain/{id}- Retrieve a chain by its numeric IDPUT /resources/chain/{id}- Update a chain by ID (requires super-user access)PATCH /resources/chain/{id}- Partially update a chain by ID (requires super-user access)
Note: The Chain resource does not support POST (creation), DELETE, or plural listing operations. Chain creation and deletion are administrative operations not available through the Resources API.
Note: PUT and PATCH operations require super-user admin access. Standard admin users can read but not modify chain properties.
Properties
The Chain resource includes the following properties, listed alphabetically:
| Name | Description | Standard Attributes(details) | Spaaza Vendor Attributes(details) |
|---|---|---|---|
allowed_business_formats | Allowed business formats for the chain | type: array nullable: true items: string | recursionLevel: 3 operations: ["put", "patch"] |
allowed_ip_ranges | IP CIDR ranges permitted to make admin login requests to this chain | type: array readOnly: true nullable: true items: AllowedIpRange | recursionLevel: 3 immutable: true |
allows_double_discounting | Whether a chain allows double discounting | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
app | App associated with the chain | type: object readOnly: true nullable: true | recursionLevel: 1 |
authentication_point | Authentication point associated with the chain | type: object readOnly: true nullable: true | recursionLevel: 2 |
basket_campaign_require_barcode_assignment | Whether a chain requires at least one barcode assignment for a BasketCampaign | type: boolean | recursionLevel: 3 immutable: false operations: ["put", "patch"] |
basket_campaign_require_format_assignment | Whether a chain requires at least one Business Format assignment for a BasketCampaign | type: boolean | recursionLevel: 3 immutable: false operations: ["put", "patch"] |
basket_campaign_require_region_or_store_assignment | Whether a chain requires at least one business or business_region assignment for a BasketCampaign | type: boolean | recursionLevel: 3 immutable: false operations: ["put", "patch"] |
basket_voucher_always_redeem_full_value_in_store | Whether to redeem full value of basket vouchers in store | type: boolean | recursionLevel: 3 |
basket_voucher_always_redeem_full_value_online | Whether to redeem full value of basket vouchers online | type: boolean | recursionLevel: 3 |
business_group_enabled | Whether a chain has business groups enabled | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
calculate_basket_on_total_value_in_store | Whether to calculate the basket on total value in store | type: boolean | recursionLevel: 3 |
calculate_basket_on_total_value_online | Whether to calculate the basket on total value online | type: boolean | recursionLevel: 3 |
chain_stores_user_signature | Whether the chain stores a user signature on transactions | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
competition_win_rate_multiplier | Scalar multiplier applied to competition win chance | type: number format: float | recursionLevel: 3 operations: ["put", "patch"] |
created_date | Chain created date | type: date-time readOnly: true | recursionLevel: 2 immutable: true |
currency | Chain currency | type: object | recursionLevel: 2 operations: ["put", "patch"] |
deleted | Whether the chain is deleted | type: boolean readOnly: true | recursionLevel: 1 |
dummy_email_domain | Chain dummy email domain | type: string format: hostname maxLength: 128 | recursionLevel: 2 operations: ["put", "patch"] |
email_address | Chain email address | type: string format: email nullable: true maxLength: 255 | recursionLevel: 2 operations: ["put", "patch"] |
enrichment_enabled | Whether transaction enrichment is enabled for the chain | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
exclude_rewards_on_basket_campaign_discounted_items | Whether rewards should be excluded for items discounted by BasketCampaigns | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
expired_vouchers_regenerate_on_return | Whether vouchers are regenerated in a return if the original voucher has expired | type: boolean | recursionLevel: 3 |
geo_codes_user_address_info | Whether a chain is set to geocode user address information | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
google_wallet_issuer_id | The Google Wallet issuer ID for the chain | type: string maxLength: 128 | recursionLevel: 3 operations: ["put", "patch"] |
id | Chain Spaaza ID | type: integer readOnly: true | recursionLevel: 0 identifier: true |
image_url | Chain image URL | type: string format: uri maxLength: 1024 | recursionLevel: 2 operations: ["put", "patch"] |
ip_whitelist_super_user_exemption | Whether super-user access exempts a user from IP address whitelisting | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
jwt_audience | Optional JWT audience expected for shopper access tokens trusted by this chain | type: string nullable: true maxLength: 255 | recursionLevel: 3 operations: ["put", "patch"] |
jwt_issuer | The JWT issuer expected for shopper access tokens trusted by this chain | type: string nullable: true maxLength: 255 | recursionLevel: 3 operations: ["put", "patch"] |
jwt_jwks_url | The JWKS URL used to validate shopper access tokens trusted by this chain | type: string format: url nullable: true maxLength: 512 | recursionLevel: 3 operations: ["put", "patch"] |
language | Chain language code (IETF/W3C format) | type: string nullable: true maxLength: 32 | recursionLevel: 2 operations: ["put", "patch"] |
last_modified_date | Chain last modified date | type: date-time readOnly: true | recursionLevel: 2 immutable: true |
last_updated_by | The user who last updated this chain | type: object readOnly: true nullable: true | recursionLevel: 2 |
name | Chain name | type: string maxLength: 255 | recursionLevel: 1 operations: ["put", "patch"] |
non_payment_state | Whether the chain is in a non-payment state | type: boolean readOnly: true | recursionLevel: 3 |
outlier_analysis_enabled | Whether outlier analysis is enabled for the chain | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
password_reset_url | The password reset URL for the chain | type: string format: url maxLength: 1024 | recursionLevel: 3 operations: ["put", "patch"] |
phone_number | Chain phone number | type: string nullable: true maxLength: 32 | recursionLevel: 2 operations: ["put", "patch"] |
receipt_logo_url | Chain receipt logo URL | type: string format: uri nullable: true maxLength: 1024 | recursionLevel: 2 operations: ["put", "patch"] |
receipts_service_active | Whether the receipts service is active for the chain | type: boolean | recursionLevel: 3 |
redeem_basket_voucher_on_negative_value_basket | Whether it is possible to redeem a basket voucher on a negatively-valued basket | type: boolean | recursionLevel: 3 |
regenerate_vouchers_on_partial_redemption | Whether non-return partial voucher redemptions regenerate the remaining voucher value | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
regenerated_rewards_redeem_immediately | Whether rewards which are regenerated during a return are redeemed immediately in that return transaction | type: boolean | recursionLevel: 3 |
return_redeem_voucher_before_cash | Whether to redeem any claimed basket voucher before spending cash in a return or exchange transaction | type: boolean | recursionLevel: 3 |
use_custom_member_numbers | Whether custom member numbers are used for users | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
uses_third_party_voucher_id | Whether a chain applies a third party voucher ID when creating vouchers | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
uses_user_address_two_field_for_shopify | Which format a chain uses for user address information when the authentication point is Shopify | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
verify_phone_numbers | Whether phone number verification is enabled for the chain | type: boolean | recursionLevel: 3 operations: ["put", "patch"] |
Property Notes
- Singular Resource: The Chain resource is always singular — it is scoped to the chain identified by the
X-Spaaza-Chain-IDheader. There is no plural/resources/chainsendpoint. - Write Access: PUT and PATCH operations require super-user admin access. Properties listed with
operations: ["put", "patch"]can be modified by super-user admins. - Read-Only Properties: Properties marked
readOnly: true(such asid,deleted,created_date,last_modified_date,last_updated_by) cannot be modified through the API. - Allowed IP Ranges: The
allowed_ip_rangesproperty contains an array of AllowedIpRange resources. These are managed through their own dedicated resource endpoint. - Recursion Levels: The
recursionLevelattribute controls at which API response detail levels each property is included.
Sample Chain JSON
Here is an example of a Chain resource as returned by the API:
{
"allowed_business_formats": ["franchise", "owned"],
"allowed_ip_ranges": [
{
"cidr": "146.188.0.0/16",
"id": 1,
"notes": "Office network"
}
],
"allows_double_discounting": false,
"app": {
"id": 501
},
"authentication_point": {
"id": 12
},
"basket_campaign_require_barcode_assignment": false,
"basket_campaign_require_format_assignment": false,
"basket_campaign_require_region_or_store_assignment": false,
"basket_voucher_always_redeem_full_value_in_store": false,
"basket_voucher_always_redeem_full_value_online": false,
"business_group_enabled": false,
"calculate_basket_on_total_value_in_store": false,
"calculate_basket_on_total_value_online": false,
"chain_stores_user_signature": false,
"competition_win_rate_multiplier": 1.0,
"created_date": "2024-03-15T10:30:00+00:00",
"currency": {
"id": 1
},
"deleted": false,
"dummy_email_domain": "example-noreply.com",
"email_address": "info@example-retail.com",
"enrichment_enabled": false,
"exclude_rewards_on_basket_campaign_discounted_items": false,
"expired_vouchers_regenerate_on_return": false,
"geo_codes_user_address_info": false,
"google_wallet_issuer_id": null,
"id": 1743,
"image_url": "https://cdn.example.com/chain-logo.png",
"ip_whitelist_super_user_exemption": false,
"jwt_audience": null,
"jwt_issuer": null,
"jwt_jwks_url": null,
"language": "en-GB",
"last_modified_date": "2026-05-20T14:22:00+00:00",
"last_updated_by": {
"id": 987
},
"name": "Example Retail Chain",
"non_payment_state": false,
"outlier_analysis_enabled": false,
"password_reset_url": null,
"phone_number": "+31 20 123 4567",
"receipt_logo_url": null,
"receipts_service_active": false,
"redeem_basket_voucher_on_negative_value_basket": false,
"regenerate_vouchers_on_partial_redemption": true,
"regenerated_rewards_redeem_immediately": false,
"return_redeem_voucher_before_cash": false,
"use_custom_member_numbers": false,
"uses_third_party_voucher_id": false,
"uses_user_address_two_field_for_shopify": false,
"verify_phone_numbers": false
}
This example shows a typical Chain resource with configuration settings. The actual properties returned depend on the requested recursion level.