# Facilipay API v2: full reference > Official Facilipay public API for third-party integrators. Covers authentication and registration, member accounts, merchant details, transactions and customers, inventory (products, categories, modifier groups), orders, campaigns, gift card liability reporting, payments, and digital gift card delivery. Each operation lists its supported authentication schemes: an API key issued from the Facilipay Dashboard (X-API-Key header) where ApiKeyAuth is shown, or a merchant JWT bearer token. For access and support, contact support@facilipay.io. - Staging server: https://api-staging.loylap.com/v2 - Production server: https://api.loylap.com/v2 Authentication schemes: - authorization: header `authorization`. JWT to authorize requests. - ApiKeyAuth: header `X-API-Key`. Machine-readable spec with every schema: https://developers.facilipay.io/openapi.json ## Redeem gift cards at a point of sale A POS takes payment from a Facilipay gift card with two calls: look the card up, then debit it. A customer's gift card value, prepaid top-ups and cashless credit at a merchant sit in one stored-value balance, so the same calls spend all three. `POST /payments` is deprecated and will be replaced by an order-based endpoint. It remains the way to redeem stored value until then. Requests that pass validation get `Deprecation` and `Sunset` headers on the response. ### 1. Create an API key In the Facilipay Dashboard, sign in as the merchant whose cards the POS will accept and create an API key with the `customers:read`, `payments:write` and `transactions:read` scopes. Send it in the `X-API-Key` header on every call. The merchant that is debited is worked out from the user who created the key: the first merchant that user owns, or failing that the first one they work at. It is not the merchant in the request. If that user owns more than one merchant, create the key from a user linked to this merchant only, or the lookup and the debit can land on another merchant. ### 2. Look up the card `GET /merchants/{merchantId}/customers/account/{accountId}`, where `accountId` is the card number: the account number printed on the card, also encoded in the QR code of the customer's wallet pass. - `balance.cash_balance` is the spendable balance in major units, returned as a decimal string: `"25.50"` means €25.50. Parse it before comparing or adding. For a franchise it is the balance across the franchise. - An unknown card returns `400` with the message `Account doesnt exist`. - A card that exists but has no registered customer returns `200` with `cardStatus: 0` and **no** `balance` object. Treat it as unusable. - Check `error` as well as the status: a key whose user has no merchant gets `200` with `"error": true` and `Merchant not found`. ### 3. Redeem `POST /payments` as `application/x-www-form-urlencoded`: | Field | Value | | --- | --- | | `payment_type` | `gift` | | `customer_id` | the card number from step 2 | | `amount` | the amount to take, in **minor units and negative**: `-2550` takes €25.50 | | `identifier` | a reference unique to this sale, e.g. your receipt number; used to check a payment after a timeout | | `terminal_id` | optional, your till or terminal id, stored on the transaction | A positive `amount` loads value onto the card instead of taking it, so always send redemptions as negative numbers. - **Success** is `200` with `{"error": false, "message": "Transaction Processed"}`. The response does not include the new balance; look the card up again if the receipt needs it. - **Balance too low.** Normally the debit is rejected in full with `401` and the message `INSUFFICIENT BALANCE`, and nothing is taken. Two merchant settings change that: a customer with a credit allowance can go below zero, and a merchant set up to charge shortfalls to the customer's saved bank card takes the difference from that card. In both cases the call succeeds. - **Split tender.** Never send more than the balance you looked up in step 2. Redeem the smaller of the balance and the bill and take the rest by another payment method; otherwise the customer can be charged twice for the difference. The balance is not locked between the lookup and the debit. - **No retries on timeout.** The call is not idempotent: sending it again debits the card again. If a request times out or returns `500` or `502`, wait at least a minute, because the payment can still complete after your request has failed. Then check it with `GET /merchants/{merchantId}/transactions/byUniqueId/{identifier}` (`transactions:read` scope). `200` with a `transaction` whose `unique_identifier` equals your `identifier` means it was applied. `404` means it was not, and you can send it again. Use identifiers that are not the start of another one, such as fixed-length receipt numbers, so a match is always yours. - Do not send an `X-API-Version` header on this call. It switches the endpoint to a different response format. ### Errors on `POST /payments` | Status | Meaning | | --- | --- | | `400` | Validation failed, unknown card (`Account doesnt exist`), expired card, or the API key's user is not an employee of the merchant (`Invalid parameters`) | | `401` | Invalid or expired API key, **or** insufficient balance (`INSUFFICIENT BALANCE`), **or** the card is blocked or expired. Check the `message` before treating it as an authentication failure | | `403` | The API key lacks the `payments:write` scope, or the customer is blocked at this merchant | | `422` | The API key is not linked to a merchant | | `500` / `502` | The payment could not be confirmed. It may or may not have been applied: wait a minute and check with `byUniqueId` before retrying | # Accounts ## Authentication ### POST /auth/refresh Renews authentication token Authentication: none. Request body (application/x-www-form-urlencoded), required: - `refresh_token`: string (e.g. "bb387a63-75b5-4a50-8026-ba14272b863f"), required. Refresh token issued at previous login Responses: - 200: Successful operation - `access_token`: string (e.g. "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjUxNzQzY2UzOWFjMzY4YWE2MTE2ZmI5MzJjMDRjYTI3In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc0ODQwMjU5fQ.2lkUbMDAdVxxgJe-F1Sr2sWRnXFM42MxPaeAY2UaoPEyK7r1sj0KcOT28Kl2g3tra2RQTLxkYv9xIrrgnAvzWA") - `refresh_token`: string (e.g. "36647f33-daa0-4e0b-9385-bc3ff2604447") - 400: Bad request - 500: Internal Server Error ### POST /auth/login/email Authenticates the user by email in the system Email and password login. Repeated failures on the account or the calling IP, or a login from a different country than the last successful one, make the API answer `406` until the request is repeated with a Google reCAPTCHA v2 token in `captcha_code`. Too many failures lock the account for a while (`423`) and notify its owner. Limited to 10 requests per minute per IP. Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | RememberMe | header | string | no | Any value extends the token lifetime | Request body (application/json): - `email`: string (email), required - `password`: string (password), required - `captcha_code`: string. Google reCAPTCHA v2 token, required after a `406` Responses: - 200: User logged in successfully - `user`: object - `user.id`: integer (int64; e.g. 3358) - `user.name`: string (e.g. "John nobody") - `user.first_name`: string (e.g. "John") - `user.last_name`: string (e.g. "Nobody") - `user.email`: string (e.g. "john.nobody@facilipay.io") - `user.username`: string (e.g. "JohnNobody") - `user.account_number`: string (e.g. "84975104JNB") - `user.photo`: string - `user.phone_number`: string - `user.gender`: string (e.g. "male") - `user.language`: string (e.g. "en") - `user.date_birth`: string (date) - `user.date_add`: integer (int64; e.g. 1407441047) - `user.date_edit`: integer (int64; e.g. 1674681548) - `user.last_group_id`: integer (int64; e.g. 217) - `user.last_branch_id`: integer (int64; e.g. 361) - `user.has_facebook`: boolean (e.g. false) - `user.has_pin`: boolean (e.g. false) - `user.card_codes`: array of string - `user.payment_cards`: object - `user.payment_cards.token`: string (e.g. 2537446225198291) - `user.payment_cards.card_type`: string (e.g. "VISA") - `user.payment_cards.expiry_date`: string (e.g. 1123) - `user.payment_cards.save_card`: boolean (e.g. true) - `user.status`: integer (e.g. 1) - `user.onboarding_type`: string - `user.save_card`: boolean (e.g. true) - `merchant`: object - `merchant.id`: integer (int64; e.g. 217) - `merchant.name`: string (e.g. "Nobodys Store") - `merchant.employee`: object - `merchant.employee.id`: integer (int64; e.g. 174) - `merchant.employee.permissions`: string (e.g. "admin") - `merchant.branch`: object - `merchant.branch.id`: integer (int64; e.g. 369) - `tokens`: object - `tokens.access_token`: string (e.g. "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjUxNzQzY2UzOWFjMzY4YWE2MTE2ZmI5MzJjMDRjYTI3In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc0ODQwMjU5fQ.2lkUbMDAdVxxgJe-F1Sr2sWRnXFM42MxPaeAY2UaoPEyK7r1sj0KcOT28Kl2g3tra2RQTLxkYv9xIrrgnAvzWA") - `tokens.refresh_token`: string (e.g. "36647f33-daa0-4e0b-9385-bc3ff2604447") - 400: Bad request - 401: Invalid credentials - 406: Captcha required, or the supplied captcha was rejected - 423: Account temporarily locked after repeated failures - 429: Too many requests - 500: Internal Server Error ### POST /auth/forgot/init/email Starts recovering a forgotten password by email Authentication: none. Request body (application/x-www-form-urlencoded), required: - `email`: string, required. Email of user Responses: - 200: Successful operation - `message`: string (e.g. "success") - 400: Bad request - 404: Email not found - 500: Internal Server Error ### POST /auth/resend-activation Re-send the account activation email Re-sends the activation link to a pending account created through `POST /member` or `POST /merchants`. Reuses the code the account already holds, so earlier links stay valid. Always answers `200` for a well-formed request, whether or not an email was sent, so the endpoint cannot be used to probe which addresses are registered. Limited to 30 requests per minute per IP. Authentication: none. Request body (application/json), required: - `email`: string (email; e.g. "jane.doe@example.com"), required - `merchant_id`: integer (int64; e.g. 253). Brand the email for this merchant and scope the activation link to it - `source`: string (one of: events). Originating app; the activation link redirects back into it Responses: - 200: Request accepted - 400: Bad request - 429: Too many requests ## Members ### POST /member Register a new member Creates a member account and emails an activation link. The account stays PENDING until the link is used, so `tokens` are only returned when the account can log in straight away. Send `temporary: true` for a guest account: it is created ACTIVE, no email is sent and `tokens` are returned immediately. `merchant_id` also enrols the member in that merchant's loyalty programme. Authentication: none. Request body (application/json), required: - `email`: string (email; e.g. "jane.doe@example.com"), required - `password`: string (password). Omit to let the member set a password from the activation link - `name`: string (e.g. "Jane Doe") - `phone_number`: string (e.g. "+353871234567") - `merchant_id`: string (e.g. "253"). Enrol the member with this merchant and brand the activation email - `card_number`: string. Existing physical card to link to the new account - `receive_updates`: boolean - `temporary`: boolean. Guest account. Created ACTIVE, no activation email, tokens returned - `onboarding_type`: integer (one of: 1, 2). USER: 1 (default), MERCHANT: 2 (owner account for a merchant sign-up) - `onboarding_source`: string (one of: events). Originating app; the activation link redirects back into it Responses: - 200: Account created - `user`: object - `user.id`: integer (int64; e.g. 3358) - `user.name`: string (e.g. "John nobody") - `user.first_name`: string (e.g. "John") - `user.last_name`: string (e.g. "Nobody") - `user.email`: string (e.g. "john.nobody@facilipay.io") - `user.username`: string (e.g. "JohnNobody") - `user.account_number`: string (e.g. "84975104JNB") - `user.photo`: string - `user.phone_number`: string - `user.gender`: string (e.g. "male") - `user.language`: string (e.g. "en") - `user.date_birth`: string (date) - `user.date_add`: integer (int64; e.g. 1407441047) - `user.date_edit`: integer (int64; e.g. 1674681548) - `user.last_group_id`: integer (int64; e.g. 217) - `user.last_branch_id`: integer (int64; e.g. 361) - `user.has_facebook`: boolean (e.g. false) - `user.has_pin`: boolean (e.g. false) - `user.card_codes`: array of string - `user.payment_cards`: object - `user.payment_cards.token`: string (e.g. 2537446225198291) - `user.payment_cards.card_type`: string (e.g. "VISA") - `user.payment_cards.expiry_date`: string (e.g. 1123) - `user.payment_cards.save_card`: boolean (e.g. true) - `user.status`: integer (e.g. 1) - `user.onboarding_type`: string - `user.save_card`: boolean (e.g. true) - `tokens`: object - `tokens.access_token`: string (e.g. "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjUxNzQzY2UzOWFjMzY4YWE2MTE2ZmI5MzJjMDRjYTI3In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc0ODQwMjU5fQ.2lkUbMDAdVxxgJe-F1Sr2sWRnXFM42MxPaeAY2UaoPEyK7r1sj0KcOT28Kl2g3tra2RQTLxkYv9xIrrgnAvzWA") - `tokens.refresh_token`: string (e.g. "36647f33-daa0-4e0b-9385-bc3ff2604447") - 400: Bad request, or the email is already registered ### GET /member/account/{accountId} Get the user information from the account ID Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | accountId | path | integer (int32; e.g. 22014505) | yes | Member account ID | Responses: - 200: Successful operation - `user`: object - `user.id`: integer (int64; e.g. 3358) - `user.name`: string (e.g. "John nobody") - `user.first_name`: string (e.g. "John") - `user.last_name`: string (e.g. "Nobody") - `user.email`: string (e.g. "john.nobody@facilipay.io") - `user.username`: string (e.g. "JohnNobody") - `user.account_number`: string (e.g. "84975104JNB") - `user.photo`: string - `user.phone_number`: string - `user.gender`: string (e.g. "male") - `user.language`: string (e.g. "en") - `user.date_birth`: string (date) - `user.date_add`: integer (int64; e.g. 1407441047) - `user.date_edit`: integer (int64; e.g. 1674681548) - `user.last_group_id`: integer (int64; e.g. 217) - `user.last_branch_id`: integer (int64; e.g. 361) - `user.has_facebook`: boolean (e.g. false) - `user.has_pin`: boolean (e.g. false) - `user.card_codes`: array of string - `user.payment_cards`: object - `user.payment_cards.token`: string (e.g. 2537446225198291) - `user.payment_cards.card_type`: string (e.g. "VISA") - `user.payment_cards.expiry_date`: string (e.g. 1123) - `user.payment_cards.save_card`: boolean (e.g. true) - `user.status`: integer (e.g. 1) - `user.onboarding_type`: string - `user.save_card`: boolean (e.g. true) - `campaigns`: array of object - `campaigns[].id`: integer (int64; e.g. 23145) - `campaigns[].status`: string (e.g. "running") - `campaigns[].name`: string (e.g. "Super campaign") - `campaigns[].description`: string (e.g. "Some description") - `campaigns[].terms`: string (e.g. "Some terms and conditions") - `campaigns[].picture`: string (e.g. "image url") - `campaigns[].schedule_period_start`: string (date; default null) - `campaigns[].schedule_period_end`: string (date; default null) - `campaigns[].limits_budget`: integer (int64; default null) - `campaigns[].limits_coupons`: integer (int64; default null) - `campaigns[].limits_coupons_user`: integer (int64; default null) - `campaigns[].limits_coupons_user_type`: string (default null) - `campaigns[].limits_value_user`: integer (int64; default null) - `campaigns[].limits_value_user_type`: string (default null) - `campaigns[].limits_budget_email`: boolean (e.g. false) - `campaigns[].limits_coupons_email`: boolean (e.g. false) - `campaigns[].highlight`: boolean (e.g. true) - `campaigns[].advertising`: boolean (e.g. true) - `campaigns[].createdAt`: string (date) - `campaigns[].updatedAt`: string (date) - `campaigns[].transactions`: array of object - `campaigns[].transactions[].rewards_value`: integer (int64; e.g. 7003922165) - `campaigns[].transactions[].coupons_quantity`: integer (int64; e.g. 2346234) - `campaigns[].rewards`: array of object - `campaigns[].rewards[].id`: integer (int64; e.g. 12345) - `campaigns[].rewards[].campaign_id`: integer (int64; e.g. 12345) - `campaigns[].rewards[].type`: string (e.g. "discount product") - `campaigns[].rewards[].value_type`: string (e.g. "percent") - `campaigns[].rewards[].value`: integer (int64; e.g. 200) - `campaigns[].rewards[].sales_value`: integer (int64; default 0; e.g. 10) - `campaigns[].rewards[].amount`: integer (int64; default 0; e.g. 200) - `campaigns[].rewards[].products_selection`: string (e.g. "{\"productsSelection\":[{\"productId\":\"26897342\",\"modifiersIdsExclusionList\":[\"1427663\"]}],\"categoriesSelection\":[]}") - `campaigns[].rewards[].item_limit`: integer (int64; e.g. 3) - `campaigns[].schedule_days`: array of object - `campaigns[].schedule_days[].id`: integer (int64; e.g. 123) - `campaigns[].schedule_days[].campaign_id`: integer (int64; e.g. 12345) - `campaigns[].schedule_days[].day`: string (e.g. "monday") - `campaigns[].schedule_periods`: array of object - `campaigns[].schedule_periods[].id`: integer (int64; e.g. 123) - `campaigns[].schedule_periods[].campaign_id`: integer (int64; e.g. 12345) - `campaigns[].schedule_periods[].period`: string (e.g. "morning") - `balance`: object - `balance.cash`: integer (default 0) - `balance.stamps`: integer (default 0) - `balance.maxStamps`: integer (default 0; e.g. 10) - `balance.creditAllowed`: boolean - 400: Bad request - 401: Invalid authentication # Merchants ## Merchant Details ### POST /merchants Register a new merchant Creates a merchant (group, default branch, owner employee, default settings) for the authenticated user, who must already exist, typically created moments earlier with `POST /member` using `onboarding_type: 2`. The body shape depends on `platform_name`. Documented here is the self-serve flow (`web`, `ios`, `android`); the POS flows (`clover`, the PAX terminal platforms, `poynt`) carry platform credentials instead and are driven by the POS apps. Authentication (any one): authorization (header `authorization`). Request body (application/json), required: - `platform_name`: string (one of: web, ios, android; e.g. "web"), required - `business_name`: string (e.g. "Nobodys Store"), required - `email`: string (email; e.g. "store@nobodys.com"), required. Email of the owner account (must match the authenticated user) - `address`: string (e.g. "1 Main Street, Dublin 2, Ireland") - `phone`: string - `website`: string (uri) - `products`: array of string. Facilipay products to enable - `category`: string. Business category name - `business_category_id`: integer (int64) - `business_subcategory_id`: integer (int64) Responses: - 200: Merchant created - `error`: string - `user`: object - `user.id`: integer (int64; e.g. 3358) - `user.name`: string (e.g. "John nobody") - `user.first_name`: string (e.g. "John") - `user.last_name`: string (e.g. "Nobody") - `user.email`: string (e.g. "john.nobody@facilipay.io") - `user.username`: string (e.g. "JohnNobody") - `user.account_number`: string (e.g. "84975104JNB") - `user.photo`: string - `user.phone_number`: string - `user.gender`: string (e.g. "male") - `user.language`: string (e.g. "en") - `user.date_birth`: string (date) - `user.date_add`: integer (int64; e.g. 1407441047) - `user.date_edit`: integer (int64; e.g. 1674681548) - `user.last_group_id`: integer (int64; e.g. 217) - `user.last_branch_id`: integer (int64; e.g. 361) - `user.has_facebook`: boolean (e.g. false) - `user.has_pin`: boolean (e.g. false) - `user.card_codes`: array of string - `user.payment_cards`: object - `user.payment_cards.token`: string (e.g. 2537446225198291) - `user.payment_cards.card_type`: string (e.g. "VISA") - `user.payment_cards.expiry_date`: string (e.g. 1123) - `user.payment_cards.save_card`: boolean (e.g. true) - `user.status`: integer (e.g. 1) - `user.onboarding_type`: string - `user.save_card`: boolean (e.g. true) - `merchant`: object - `merchant.id`: integer (int64; e.g. 217) - `merchant.name`: string (e.g. "Nobodys Store") - `merchant.employee`: object - `merchant.employee.id`: integer (int64; e.g. 174) - `merchant.employee.permissions`: string (e.g. "admin") - `merchant.branch`: object - `merchant.branch.id`: integer (int64; e.g. 369) - `tokens`: object - `tokens.access_token`: string (e.g. "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjUxNzQzY2UzOWFjMzY4YWE2MTE2ZmI5MzJjMDRjYTI3In0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc0ODQwMjU5fQ.2lkUbMDAdVxxgJe-F1Sr2sWRnXFM42MxPaeAY2UaoPEyK7r1sj0KcOT28Kl2g3tra2RQTLxkYv9xIrrgnAvzWA") - `tokens.refresh_token`: string (e.g. "36647f33-daa0-4e0b-9385-bc3ff2604447") - 400: Bad request, unknown platform_name, or the owner already has a merchant - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId} Returns merchant details Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `[].id`: integer (int64; e.g. 217) - `[].name`: string (e.g. "Nobodys Store") - `[].caterer`: boolean - `[].group_admin_email`: string (e.g. "admin@example.com") - `[].short_name`: string (e.g. "Nobodys Store") - `[].email`: string (e.g. "store@nobodys.com") - `[].phone`: string (e.g. "961 770 7727") - `[].website`: string (e.g. "https://www.loylap.com") - `[].url`: string (e.g. "https://nobodys.loylap.com") - `[].slug`: string (e.g. "nobodys") - `[].category`: integer (int64; e.g. "1495,") - `[].category_name`: string (e.g. "Video Game Arcades/Establishments") - `[].visible`: string (one of: 0, 1; default 1) - `[].status`: integer (one of: 0, 1; default 1) - `[].access_level`: integer (default 0) - `[].established`: string (date-time) - `[].location`: object - `[].location.address`: string (e.g. "Pickering, ON, Canada") - `[].location.lat`: string (e.g. -2.9114) - `[].location.lng`: string (e.g. -117.2256) - `[].location.country`: string (e.g. "CA") - `[].location.zip`: string (e.g. 30262) - `[].location.city`: string (e.g. "West Darronfort") - `[].isEnrolled`: boolean - `[].isParent`: boolean - `[].features`: object - `[].features.topup`: boolean (e.g. true) - `[].features.integrations`: object - `[].features.integrations.aibms`: boolean (e.g. false) - `[].features.integrations.aibms_id`: string - `[].features.integrations.stripe`: boolean (e.g. true) - `[].features.integrations.stripe_id`: string (e.g. "8P9KC4AW3N8FSP4LLTZN") - `[].features.integrations.judopay`: boolean (e.g. false) - `[].features.integrations.judopay_id`: string - `[].features.integrations.clover_ecomm`: boolean (e.g. false) - `[].features.integrations.clover_ecomm_id`: string - `[].photos`: object - `[].photos.group_photo`: string - `[].photos.img1`: string - `[].photos.img2`: string - `[].photos.img3`: string - `[].photos.img4`: string - `[].branches`: array of object - `[].branches[].id`: integer (int64; e.g. 4474) - `[].branches[].name`: string (e.g. "Spire's Branch") - `[].branches[].address`: string (e.g. "0954 Heather Via Apt. 755") - `[].branches[].lat`: string (e.g. 78.5098) - `[].branches[].lng`: string (e.g. -153.7968) - `[].branches[].phone`: string (e.g. "961 770 7727") - `[].branches[].opening_hours`: string (e.g. "[{\"day\":\"Saturday\",\"from\":\"00:00\",\"to\":\"23:59\",\"isOpen\":false},{\"day\":\"Thursday\",\"from\":\"00:00\",\"to\":\"23:59\",\"isOpen\":false},{\"day\":\"Friday\",\"from\":\"00:00\",\"to\":\"23:59\",\"isOpen\":false},{\"day\":\"Sunday\",\"from\":\"00:00\",\"to\":\"00:00\",\"isOpen\":false},{\"day\":\"Monday\",\"from\":\"08:00\",\"to\":\"23:00\",\"isOpen\":false}]"). A JSON stringified - `[].branches[].delivery_type`: string (one of: , both, collection, delivery, none, pickup; default null) - `[].branches[].external_merchant_id`: string (e.g. "9BFO4O39GQZ435") - `[].branches[].estimated_delivery`: string (default null) - `[].branches[].estimated_collection`: string (default null) - `[].branches[].group_id`: integer (int64; e.g. 201) - `[].branches[].status`: integer (one of: 0, 1) - `[].branches[].is_phone_number_required_for_ordering`: boolean (default false) - `[].branches[].fixed_delivery_name`: string - `[].branches[].max_delivery_distance`: number (default 0) - `[].branches[].delivery`: boolean (default false) - `[].branches[].tip`: boolean (default false) - `[].branches[].hide_calendar`: boolean (default false) - `[].branches[].ordering`: integer (one of: 0, 1) - `[].branches[].prep_time`: number (e.g. 50) - `[].branches[].add_utensils`: integer (default 0) - `[].branches[].delivery_time`: string (default 0) - `[].branches[].fixed_delivery_time`: string (default 0) - `[].branches[].delivery_addresses`: array of object - `[].branches[].delivery_addresses[].id`: integer (int64; e.g. 2) - `[].branches[].delivery_addresses[].user_id`: integer (int64; default null) - `[].branches[].delivery_addresses[].group_id`: integer (int64; e.g. 201) - `[].branches[].delivery_addresses[].branch_id`: integer (int64; e.g. 234) - `[].branches[].delivery_addresses[].is_primary`: boolean - `[].branches[].delivery_addresses[].country`: string (default null) - `[].branches[].delivery_addresses[].postal_code`: string (default null) - `[].branches[].delivery_addresses[].region`: string (default null) - `[].branches[].delivery_addresses[].city`: string (default null) - `[].branches[].delivery_addresses[].locality`: string (default null) - `[].branches[].delivery_addresses[].line_1`: string (default null; e.g. "Room 1") - `[].branches[].delivery_addresses[].line_2`: string (default null) - `[].branches[].delivery_addresses[].line_3`: string (default null) - `[].branches[].delivery_fee`: integer (default 0) - `[].branches[].fixed_delivery_fee`: integer (default null) - `[].branches[].waive_fixed_delivery_fee`: string (default null) - `[].branches[].waive_delivery_fee`: string (default null) - `[].branches[].minimum_order_collection`: string (default 0) - `[].branches[].minimum_order_delivery`: string (default 0) - `[].branches[].minimum_order_fixed_delivery`: string (default 0) - `[].branches[].ordering_unavailable_until`: string (default null) - `[].branches[].hide_dispatch_time`: boolean (default false) - `[].branches[].ordering_welcome_message`: string (default null) - `[].branches[].modifierGroupsScroll`: boolean (default false) - `[].branches[].autoAcceptOrders`: boolean (default false) - `[].branches[].collection`: object - `[].branches[].collection.dispatch_slots`: boolean (default false) - `[].branches[].Delivery`: object - `[].branches[].Delivery.dispatch_slots`: boolean (default false) - `[].branches[].fixed-delivery`: object - `[].branches[].fixed-delivery.dispatch_slots`: boolean (default false) - `[].employees`: array of object - `[].employees[].id`: integer (int64; e.g. 574) - `[].employees[].name`: string (e.g. "John nobody") - `[].employees[].firstName`: string (e.g. "John") - `[].employees[].lastName`: string (e.g. "Nobody") - `[].employees[].status`: string (one of: enabled, disabled) - `[].employees[].permissions`: string (one of: basic, admin) - `[].employees[].role`: string (one of: basic, manager, admin) - `[].employees[].branch`: object - `[].employees[].branch.name`: string (e.g. "Spire's Branch") - `[].franchise`: array of object - `[].franchise[].id`: integer (int64; e.g. 231) - `[].franchise[].name`: string (e.g. "Franchise 1") - `[].roles`: array of string - `[].loyaltyRoles`: array of object - `[].loyaltyRoles[].id`: integer (int64; e.g. 361) - `[].loyaltyRoles[].name`: string (e.g. "Managers") - `[].settings`: array of object - `[].settings[].id`: integer (int64; e.g. 158) - `[].settings[].group_id`: integer (int64; e.g. 201) - `[].settings[].branch_id`: integer (int64; default null) - `[].settings[].value`: string - `[].settings[].data_type`: string (one of: enum, boolean, string, number, array) - `[].settings[].setting_type`: string - `[].settings[].name`: string - `[].plan`: object - `[].plan.id`: integer (int64; e.g. 1391) - `[].plan.is_active`: integer (e.g. 1) - `[].plan.group_id`: integer (int64; e.g. 201) - `[].plan.name`: string (e.g. "Starter") - `[].plan.description`: string (e.g. "Advanced Loyalty with POS Integration") - `[].plan.type`: string (e.g. "general") - `[].plan.loylap_plan`: string (e.g. "Starter") - `[].plan.extend_plan`: string (e.g. "Free") - `[].plan.country`: string (e.g. "US") - `[].plan.subscription_fee`: number (e.g. 0.1) - `[].plan.transaction_fee_gift`: number (e.g. 0) - `[].plan.transaction_fee_upfront`: number (e.g. 0) - `[].plan.transaction_charge_gift`: number (e.g. 0) - `[].plan.transaction_charge_upfront`: number (e.g. 0) - `[].plan.ordering_fee`: number (e.g. 0) - `[].plan.branch_charge`: number (e.g. 0) - `[].plan.device_charge`: number (e.g. 0) - `[].plan.free_transaction_value`: number (e.g. 500) - `[].plan.trial_days`: integer (e.g. 7) - `[].plan.remaining_trial_days`: integer (e.g. 0) - `[].plan.last_billed`: string (date; default null) - `[].plan.next_bill_date_to_charge`: string (date) - `[].plan.acquirer`: string (default null) - `[].plan.gateway`: string (default null) - `[].plan.is_direct_debit`: integer (one of: 0, 1) - `[].plan.is_invoiced_manually`: integer (one of: 0, 1; default null) - `[].plan.is_best_investment`: integer (one of: 0, 1) - `[].plan.start_date`: string (date) - `[].plan.end_date`: string (date; default null) - `[].plan.is_free`: integer (one of: 0, 1) - `[].cardDetails`: object (default null) - `[].cardDetails.card_brand`: string (e.g. "Visa") - `[].cardDetails.last_four`: string (e.g. 3436) - `[].cardDetails.expiry_date`: string (e.g. "12/26") - `[].loyalty`: object - `[].loyalty.loyalty_type`: string (one of: stamp, cash) - `[].loyalty.maximum_reward_value`: integer (e.g. 0) - `[].loyalty.stamp_number`: integer (e.g. 10) - `[].loyalty.base_reward`: number (e.g. 10) - `[].loyalty.maximum_credit_allowance`: number (e.g. 5000) - `[].loyalty.terms_and_conditions`: string - `[].loyalty.tier_type`: string (one of: spend, visits) - `[].loyalty.expiry_days`: integer (e.g. 0) - `[].loyalty.preauthorised`: boolean (e.g. true) - `[].loyalty.tiers`: object - `[].loyalty.tiers.stamp`: array of object - `[].loyalty.tiers.stamp[].amount`: integer (e.g. 10) - `[].loyalty.tiers.stamp[].reward`: integer (default "") - `[].loyalty.tiers.credit`: array of object - `[].loyalty.tiers.credit[].amount`: integer (e.g. 500) - `[].loyalty.tiers.credit[].reward`: integer (e.g. 20) - `[].loyalty.tiers.upfront`: array of object - `[].loyalty.tiers.upfront[].amount`: integer (default "") - `[].loyalty.tiers.upfront[].reward`: integer (e.g. 9) - `[].balance`: object - `[].balance.cash`: integer (default 0) - `[].balance.stamps`: integer (default 0) - `[].balance.maxStamps`: integer (default 0; e.g. 10) - `[].balance.creditAllowed`: boolean - `[].topup`: object - `[].topup.auto`: boolean - `[].topup.value`: integer - `[].paymentAccounts`: array of object - `[].paymentAccounts[].type`: string (e.g. "clover") - `[].paymentAccounts[].account_number`: string (e.g. "S2R8X3LEMKSMP") - `[].paymentAccounts[].secret`: string (e.g. "cfbb00d2-6dfd-4de7-ac17-a29699cdba23") - `[].posTokens`: object - `[].posTokens.clover`: object - `[].posTokens.clover.hasSelfCheckoutAccessToken`: boolean (e.g. true) - 400: Invalid merchant id - 404: Merchant not found ## Customers ### GET /merchants/{merchantId}/customers/v2 list customers Filters list of merchant's customers use for Pagination Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | Numeric ID of the merchant to get all customers | | exports_to | query | string (default "csv") | no | The flag used to export the list as CSV | | offset | query | integer (default 0; e.g. 10) | no | The number of customers to skip before starting to collect the list of customers | | limit | query | integer (default 10; e.g. 20) | no | The numbers of customers to return in a list of customers | | order | query | string (default "id"; e.g. "balance") | no | The sorting key to return the list of customers | | direction | query | string (one of: asc, desc; default "asc"; e.g. "desc") | no | The sorting direction to return the list of customers | | q | query | string (e.g. "nobody") | no | The filtering text to return the list of customers | | qfields | query | object (one of: name, email, nickname, card_number, balance, stamp, status) | no | Select the fields to return in the list | | gq | query | object | no | Global Search for advanced filter, read more about in https://github.com/conorot/api-service/wiki/Global-Search | | view_all | query | string (default true; e.g. true) | no | Get list of all customers | Responses: - 200: Successful operation - `total`: integer (e.g. 43590) - `data`: array of object - `data[].status`: string (e.g. "enable") - `data[].id`: integer (int64; e.g. 12345) - `data[].name`: string (e.g. "Thompson nobody") - `data[].email`: string (e.g. "Thompson.nobody@facilipay.io") - `data[].username`: string (e.g. 72345678) - `data[].nickname`: string (e.g. "Maxwello") - `data[].account_number`: string (e.g. 2346754) - `data[].photo`: string (e.g. "https://www.gravatar.com/avatar/cdd094f4455ae329a9e5a4f17e58d813?s=200&d=retro") - `data[].phone_number`: string (e.g. "+31613828447123") - `data[].gender`: string (e.g. "female") - `data[].language`: string (e.g. "en") - `data[].date_birth`: string (e.g. "2020-02-22") - `data[].age`: integer (int64; e.g. 4) - `data[].customer_since`: string (e.g. "2016-07-18") - `data[].visits`: integer (int64; e.g. 22) - `data[].last_visit`: string (e.g. "2018-06-06") - `data[].has_facebook`: boolean (e.g. false) - `data[].has_pin`: boolean (e.g. true) - `data[].card_codes`: array of string - `data[].payment_cards`: object - `data[].payment_cards.card_type`: string (e.g. "mastercard") - `data[].payment_cards.expiry_date`: string (e.g. 1222) - `data[].payment_cards.save_card`: boolean (e.g. false) - `data[].modifiers`: object - `data[].modifiers.personal_reward`: integer (e.g. 2) - `data[].modifiers.credit_allowed`: boolean (e.g. true) - `data[].modifiers.customer_note`: string (e.g. "test") - `data[].modifiers.role`: string (default null) - `data[].loyalty`: object - `data[].loyalty.merchant_id`: integer (e.g. 201) - `data[].loyalty.expiry_days`: string (e.g. 1222) - `data[].loyalty.date_edit`: string (date) - `data[].balance`: object - `data[].balance.cash`: number (default 0; e.g. 0) - `data[].balance.stamp`: integer (default 0; e.g. 0) - `data[].balance.expiry_date`: string (default "") - `data[].spending`: object - `data[].spending.credit`: object - `data[].spending.credit.earned`: number (default 0; e.g. 22.02) - `data[].spending.credit.redeemed`: number (default 0; e.g. 22.02) - `data[].spending.stamp`: object - `data[].spending.stamp.earned`: number (default 0; e.g. 22.02) - `data[].spending.stamp.redeemed`: number (default 0; e.g. 22.02) - `data[].spending.topups`: object - `data[].spending.topups.gift`: number (default 0; e.g. 22.02) - `data[].spending.topups.cashless`: number (default 0; e.g. 22.02) - `data[].spending.topups.upfront`: number (default 0; e.g. 22.02) - `data[].spending.stats`: object - `data[].spending.stats.total`: number (default 0; e.g. 222.02) - `data[].spending.stats.trend`: number (default 0; e.g. -2.16) - `data[].spending.stats.average`: number (default 0; e.g. 22.02) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /merchants/{merchantId}/customers/account/{accountId} Look up a customer and balance by card number Returns the customer behind a card number, with their balance at the merchant resolved from the API key's user (as for `POST /payments`). `balance.cash_balance` is the spendable stored-value balance (gift card, prepaid and cashless credit combined) as a decimal string in major units: `"25.50"` is €25.50. Use it before a `POST /payments` redemption, which takes minor units. An unknown card returns `400` with `Account doesnt exist`; a card with no registered customer returns `200` with `cardStatus: 0` and no `balance`. Accepts an API key with the `customers:read` scope. Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | Numeric ID of the merchant to get all customers | | accountId | path | string (e.g. 12345678) | yes | The card number (account number) printed on the card or encoded in the wallet pass QR code | Responses: - 200: Successful operation - body variant 1: - `error`: boolean (default false) - `balance`: object - `balance.id`: number - `balance.cash_balance`: string (decimal; e.g. "25.50"). Spendable stored-value balance (gift card, prepaid and cashless credit combined) in major units, as a decimal string; "25.50" is €25.50. - `balance.stamp_balance`: number (default 0) - `balance.date_edit`: number. Unix Timestamp - `balance.customer_note`: string - `balance.credit_allowed`: number - `balance.personal_reward`: number - `balance.surcharge`: number - `balance.auto_topup`: number - `balance.role`: string - `balance.tiers`: object - `balance.tiers.customer_levels`: integer (e.g. 3) - `balance.tiers.user_tier`: integer (e.g. 1) - `cardStatus`: integer (one of: 0, 1) - `details`: object - `details.id`: integer (int64; e.g. 3358) - `details.first_name`: string (e.g. "John") - `details.last_name`: string (e.g. "Nobody") - `details.nickname`: string - `details.photo`: string (e.g. "https://www.gravatar.com/avatar/1fbb84bc9211d3f42c08b9f7bf007572?s=200&d=retro") - `details.email`: string (e.g. "john.nobody@facilipay.io") - `details.phone_number`: string - `details.username`: string (e.g. "JohnNobody") - `details.account_number`: string (e.g. "84975104JNB") - `details.account_id`: string (e.g. "84975104JNB") - `details.cvv`: string (e.g. 123) - `details.card_codes`: string (e.g. "84975104JNB") - `details.status`: number (e.g. 2) - `details.date_register`: number (e.g. 1683818618). Unix Timestamp - `details.date_birth`: string (date; e.g. "1999-05-10T00:00:00.000Z") - `details.activation_code`: string - `details.new_password`: string (e.g. 1) - `details.new_password_code`: string - `details.fb_id`: string - `details.popdeem_rewards`: number (e.g. 0) - `details.payeezy_token`: string - `details.expiry_date`: string (e.g. 1225) - `details.card_type`: string (e.g. "visa debit") - `details.scheme_transaction_id`: string - `details.save_payment_details`: string - `details.stripe_user_token`: string - `details.stripe_customer_id`: string - `details.stripe_subscription_id`: string - `details.gocardless_customer_id`: string - `details.gocardless_mandate_id`: string - `details.gocardless_subscription_id`: string - `details.date_add`: number (e.g. 1683818618). Unix Timestamp - `details.device_token`: string - `details.gcm_id`: string - `details.apn_id`: string - `details.gender`: integer (e.g. 1) - `details.last_group_id`: integer (int64; e.g. 217) - `details.last_branch_id`: integer (int64; e.g. 316) - `details.employee`: integer (e.g. 1) - `details.owner`: integer (e.g. 0) - `details.lang`: string (e.g. "en") - `campaigns`: object - `campaigns.error`: string - body variant 2: - `error`: boolean (default false) - `details`: object - `details.status`: integer (default 0) - `cardStatus`: integer (default 0) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### POST /merchants/{merchantId}/customers/cards Register a card Registers a new card OR updates existing card Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Request body (application/json): - `name`: string, required - `email`: string - `date_of_birth`: string (date) - `gender`: string (one of: male, female, other, unknown) - `card_number`: string Responses: - 200: Successful operation - `account_number`: string (e.g. 84975104) - `error`: boolean (e.g. false) - `balance`: object - `balance.id`: number - `balance.cash_balance`: string (decimal; e.g. "25.50"). Spendable stored-value balance (gift card, prepaid and cashless credit combined) in major units, as a decimal string; "25.50" is €25.50. - `balance.stamp_balance`: number (default 0) - `balance.date_edit`: number. Unix Timestamp - `balance.customer_note`: string - `balance.credit_allowed`: number - `balance.personal_reward`: number - `balance.surcharge`: number - `balance.auto_topup`: number - `balance.role`: string - `cardStatus`: number (e.g. 0) - `details`: object - `details.id`: integer (int64; e.g. 3358) - `details.first_name`: string (e.g. "John") - `details.last_name`: string (e.g. "Nobody") - `details.nickname`: string - `details.photo`: string (e.g. "https://www.gravatar.com/avatar/1fbb84bc9211d3f42c08b9f7bf007572?s=200&d=retro") - `details.email`: string (e.g. "john.nobody@facilipay.io") - `details.phone_number`: string - `details.username`: string (e.g. "JohnNobody") - `details.account_number`: string (e.g. "84975104JNB") - `details.account_id`: string (e.g. "84975104JNB") - `details.cvv`: string (e.g. 123) - `details.card_codes`: string (e.g. "84975104JNB") - `details.status`: number (e.g. 2) - `details.date_register`: number (e.g. 1683818618). Unix Timestamp - `details.date_birth`: string (date; e.g. "1999-05-10T00:00:00.000Z") - `details.activation_code`: string - `details.new_password`: string (e.g. 1) - `details.new_password_code`: string - `details.fb_id`: string - `details.popdeem_rewards`: number (e.g. 0) - `details.payeezy_token`: string - `details.expiry_date`: string (e.g. 1225) - `details.card_type`: string (e.g. "visa debit") - `details.scheme_transaction_id`: string - `details.save_payment_details`: string - `details.stripe_user_token`: string - `details.stripe_customer_id`: string - `details.stripe_subscription_id`: string - `details.gocardless_customer_id`: string - `details.gocardless_mandate_id`: string - `details.gocardless_subscription_id`: string - `details.date_add`: number (e.g. 1683818618). Unix Timestamp - `details.device_token`: string - `details.gcm_id`: string - `details.apn_id`: string - `details.gender`: integer (e.g. 1) - `details.last_group_id`: integer (int64; e.g. 217) - `details.last_branch_id`: integer (int64; e.g. 316) - `details.employee`: integer (e.g. 1) - `details.owner`: integer (e.g. 0) - `details.lang`: string (e.g. "en") - `historyOverview`: object - `historyOverview.total_visits`: number (e.g. 0) - `historyOverview.period_visits`: number (e.g. 0) - `historyOverview.period`: number (e.g. 730) - `historyOverview.total_spend`: string (e.g. "Not applicable") - `historyOverview.period_spend`: string (e.g. "Not applicable") - `historyOverview.silver_reward`: string (e.g. "free reward") - `historyOverview.gold_reward`: number - `historyOverview.platinum_reward`: number - `historyOverview.number_redeems`: number (e.g. 0) - `historyOverview.amount_redeems`: string (e.g. "Not applicable") - `historyOverview.monthly_visits`: number (e.g. 0) - `historyOverview.monthly_spend`: string (e.g. "Not applicable") - `historyOverview.monthly_rank`: number (e.g. 0) - `historyOverview.reward_tier_1`: number (e.g. 10) - `historyOverview.reward_tier_2`: number (e.g. 0) - `historyOverview.reward_tier_3`: number (e.g. 0) - `historyOverview.reward_tier_4`: number (e.g. 0) - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /merchants/{merchantId}/customers/activate-account Activate Account activate account OR updates existing account Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Request body (application/json): - `full_name`: string, required - `email`: string, required - `date_of_birth`: string (date), required - `gender`: string (one of: male, female, other, unknown), required - `loyalty_id`: string, required - `password`: string, required Responses: - 200: Successful operation - `error`: boolean (e.g. false) - `balance`: object - `balance.id`: number - `balance.cash_balance`: string (decimal; e.g. "25.50"). Spendable stored-value balance (gift card, prepaid and cashless credit combined) in major units, as a decimal string; "25.50" is €25.50. - `balance.stamp_balance`: number (default 0) - `balance.date_edit`: number. Unix Timestamp - `balance.customer_note`: string - `balance.credit_allowed`: number - `balance.personal_reward`: number - `balance.surcharge`: number - `balance.auto_topup`: number - `balance.role`: string - `cardStatus`: number (e.g. 0) - `details`: object - `details.id`: integer (int64; e.g. 3358) - `details.first_name`: string (e.g. "John") - `details.last_name`: string (e.g. "Nobody") - `details.nickname`: string - `details.photo`: string (e.g. "https://www.gravatar.com/avatar/1fbb84bc9211d3f42c08b9f7bf007572?s=200&d=retro") - `details.email`: string (e.g. "john.nobody@facilipay.io") - `details.phone_number`: string - `details.username`: string (e.g. "JohnNobody") - `details.account_number`: string (e.g. "84975104JNB") - `details.account_id`: string (e.g. "84975104JNB") - `details.cvv`: string (e.g. 123) - `details.card_codes`: string (e.g. "84975104JNB") - `details.status`: number (e.g. 2) - `details.date_register`: number (e.g. 1683818618). Unix Timestamp - `details.date_birth`: string (date; e.g. "1999-05-10T00:00:00.000Z") - `details.activation_code`: string - `details.new_password`: string (e.g. 1) - `details.new_password_code`: string - `details.fb_id`: string - `details.popdeem_rewards`: number (e.g. 0) - `details.payeezy_token`: string - `details.expiry_date`: string (e.g. 1225) - `details.card_type`: string (e.g. "visa debit") - `details.scheme_transaction_id`: string - `details.save_payment_details`: string - `details.stripe_user_token`: string - `details.stripe_customer_id`: string - `details.stripe_subscription_id`: string - `details.gocardless_customer_id`: string - `details.gocardless_mandate_id`: string - `details.gocardless_subscription_id`: string - `details.date_add`: number (e.g. 1683818618). Unix Timestamp - `details.device_token`: string - `details.gcm_id`: string - `details.apn_id`: string - `details.gender`: integer (e.g. 1) - `details.last_group_id`: integer (int64; e.g. 217) - `details.last_branch_id`: integer (int64; e.g. 316) - `details.employee`: integer (e.g. 1) - `details.owner`: integer (e.g. 0) - `details.lang`: string (e.g. "en") - `historyOverview`: object - `historyOverview.total_visits`: number (e.g. 0) - `historyOverview.period_visits`: number (e.g. 0) - `historyOverview.period`: number (e.g. 730) - `historyOverview.total_spend`: string (e.g. "Not applicable") - `historyOverview.period_spend`: string (e.g. "Not applicable") - `historyOverview.silver_reward`: string (e.g. "free reward") - `historyOverview.gold_reward`: number - `historyOverview.platinum_reward`: number - `historyOverview.number_redeems`: number (e.g. 0) - `historyOverview.amount_redeems`: string (e.g. "Not applicable") - `historyOverview.monthly_visits`: number (e.g. 0) - `historyOverview.monthly_spend`: string (e.g. "Not applicable") - `historyOverview.monthly_rank`: number (e.g. 0) - `historyOverview.reward_tier_1`: number (e.g. 10) - `historyOverview.reward_tier_2`: number (e.g. 0) - `historyOverview.reward_tier_3`: number (e.g. 0) - `historyOverview.reward_tier_4`: number (e.g. 0) - `history`: object - `history.id_customer`: number (e.g. 23456789) - `history.id_business`: number (e.g. 2345) - `history.amount`: number (e.g. 2345) - `history.time`: string (date-time; e.g. "2023-02-20T22:06:40.000Z") - `history.timestamp`: integer (e.g. 1676930800) - `history.transaction_type`: string (e.g. "add") - `history.id_group`: number (e.g. 176) - `history.group_name`: string (e.g. "Pals Pizza") - `history.loyaltyType`: string (e.g. "gift") - `history.short_name`: string (e.g. "Pals Pizza") - `history.branch_name`: string (e.g. "Branch name") - `history.unique_identifier`: string (e.g. "645e464ba7cc1 | Insertion time: 16838999796 | Customer ID: 554046543 | Amount: 200") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId}/customers/{customerId} Returns a customer details Returns a specific customer details at a merchant Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | customerId | path | integer (int64; e.g. 162) | yes | ID of customer | Responses: - 200: Successful operation - `status`: string (e.g. "enable") - `id`: integer (int64; e.g. 12345) - `name`: string (e.g. "Thompson nobody") - `email`: string (e.g. "Thompson.nobody@facilipay.io") - `username`: string (e.g. 72345678) - `nickname`: string (e.g. "Maxwello") - `account_number`: string (e.g. 2346754) - `photo`: string (e.g. "https://www.gravatar.com/avatar/cdd094f4455ae329a9e5a4f17e58d813?s=200&d=retro") - `phone_number`: string (e.g. "+31613828447123") - `gender`: string (e.g. "female") - `language`: string (e.g. "en") - `date_birth`: string (e.g. "2020-02-22") - `age`: integer (int64; e.g. 4) - `customer_since`: string (e.g. "2016-07-18") - `visits`: integer (int64; e.g. 22) - `last_visit`: string (e.g. "2018-06-06") - `has_facebook`: boolean (e.g. false) - `has_pin`: boolean (e.g. true) - `card_codes`: array of string - `payment_cards`: object - `payment_cards.card_type`: string (e.g. "mastercard") - `payment_cards.expiry_date`: string (e.g. 1222) - `payment_cards.save_card`: boolean (e.g. false) - `modifiers`: object - `modifiers.personal_reward`: integer (e.g. 2) - `modifiers.credit_allowed`: boolean (e.g. true) - `modifiers.customer_note`: string (e.g. "test") - `modifiers.role`: string (default null) - `loyalty`: object - `loyalty.merchant_id`: integer (e.g. 201) - `loyalty.expiry_days`: string (e.g. 1222) - `loyalty.date_edit`: string (date) - `balance`: object - `balance.cash`: number (default 0; e.g. 0) - `balance.stamp`: integer (default 0; e.g. 0) - `balance.expiry_date`: string (default "") - `spending`: object - `spending.credit`: object - `spending.credit.earned`: number (default 0; e.g. 22.02) - `spending.credit.redeemed`: number (default 0; e.g. 22.02) - `spending.stamp`: object - `spending.stamp.earned`: number (default 0; e.g. 22.02) - `spending.stamp.redeemed`: number (default 0; e.g. 22.02) - `spending.topups`: object - `spending.topups.gift`: number (default 0; e.g. 22.02) - `spending.topups.cashless`: number (default 0; e.g. 22.02) - `spending.topups.upfront`: number (default 0; e.g. 22.02) - `spending.stats`: object - `spending.stats.total`: number (default 0; e.g. 222.02) - `spending.stats.trend`: number (default 0; e.g. -2.16) - `spending.stats.average`: number (default 0; e.g. 22.02) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Transactions ### GET /merchants/{merchantId}/transactions/byUniqueId/{uniqueIdentifier} Find a transaction by your identifier Returns the merchant's stored-value transaction whose identifier is `uniqueIdentifier`, usually the `identifier` sent to `POST /payments`; if none matches exactly, one whose identifier starts with it. Compare the returned `unique_identifier` with yours. Reads the primary database, so a payment that has completed is always found. Use it after a timeout, `500` or `502` to check whether a redemption was applied before retrying. Accepts an API key with the `transactions:read` scope. Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | Numeric ID of the merchant | | uniqueIdentifier | path | string (e.g. "POS-1042-000731") | yes | The `identifier` sent with the payment, or its beginning | Responses: - 200: A matching transaction exists, so the payment was applied. - `transaction`: object. The stored-value ledger row (amount, type, dates). - `transaction.unique_identifier`: string. The identifier stored with the payment. Check it equals yours. - 404: No transaction with this identifier, so the payment was not applied. ### GET /merchants/{merchantId}/transactions/v2 List merchant transaction Filters list of merchant's transaction use for Pagination Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | Numeric ID of merchant to get all transaction | | exports_to | query | string (default "csv") | no | The flag used to export the list as CSV | | offset | query | integer (default 0; e.g. 10) | no | The number of merchant transaction to skip before starting to collect the list of merchant transaction | | limit | query | integer (default 10; e.g. 20) | no | The numbers of transaction to return in a list of merchant transaction | | order | query | string (default "id"; e.g. "desc") | no | The sorting key to return the list of merchant transaction | | view_all | query | string (default true; e.g. true) | no | Get list of all customers | | qfields | query | object (one of: name, date_add, amount, payment_type, transaction_type, account_id, merchant_id, branch_id, employee_id, customer_id) | no | Select the fields to return in the list | | gq | query | object | no | Global Search for advanced filter, read more about in https://github.com/conorot/api-service/wiki/Global-Search | Responses: - 200: Successful operation - `total`: integer (e.g. 76854) - `data`: array of object - `data[].customer`: object - `data[].customer.id`: integer (e.g. 12345) - `data[].customer.name`: string (e.g. "Thompson") - `data[].customer.card_codes`: array of string - `data[].merchant`: object - `data[].merchant.id`: integer (e.g. 45) - `data[].merchant.name`: string (e.g. "Thompson Pizza") - `data[].branch`: object - `data[].branch.id`: integer (e.g. 275) - `data[].branch.name`: string (e.g. "Retail Excellence") - `data[].employee`: object - `data[].employee.id`: integer (e.g. 275) - `data[].employee.name`: string (e.g. "Thompson Nobody") - `data[].payment_type`: string (e.g. "stamp") - `data[].transaction_type`: string (e.g. "add") - `data[].sale_total`: number (e.g. 10) - `data[].amount`: number (e.g. 1000) - `data[].rewards`: array of string (default []) - `data[].refunded`: boolean (e.g. true) - `data[].voided`: boolean (e.g. false) - `data[].details`: object - `data[].details.transaction`: object - `data[].details.transaction.uid`: string (e.g. "f2t9lbbx8xhy5j3z | Transaction type: Redeem Gift | Amount: 672 | Insertion time: 1675088546761 | Order ID: 9HGJ7QXTYFWTK | Order Total: 0 | Order Access time: 0 | Customer balance: 106269 | Customer ID: 12345 | Employee: Lite - No employee | Email: thompson.nobody@facilipay.io | Note: Cashless, customer facing redeem") - `data[].details.transaction.amount`: number (e.g. 673) - `data[].details.transaction.insertion_time`: integer (e.g. 1675088546761) - `data[].details.transaction.transaction_type`: string (e.g. "Redeem Gift") - `data[].details.transaction.order_id`: string (e.g. "9HGJ7QXTYFWTK") - `data[].details.transaction.order_access_time`: integer (default 0; e.g. 1674727178204) - `data[].details.transaction.order_total`: number (default 0; e.g. 600) - `data[].details.transaction.order_line_items`: array of object (default "None") - `data[].details.transaction.customer_id`: string (e.g. "12345") - `data[].details.transaction.customer_balance`: number (e.g. 106269) - `data[].details.transaction.customer_personal_reward`: integer (e.g. -1) - `data[].details.transaction.cashback_rewards`: string (e.g. "N/A") - `data[].details.transaction.note`: string (e.g. "Cashless, customer facing redeem") - `data[].details.transaction.attempts`: integer (e.g. 1) - `data[].details.device`: object - `data[].details.device.employee`: string (e.g. "Lite - No employee") - `data[].details.device.package`: string (e.g. "com.sp.vendor") - `data[].details.device.version`: integer (e.g. 820) - `data[].details.device.model`: string (e.g. "C503") - `data[].details.device.serial`: string (e.g. "C053EQ92470015") - `data[].unique_identifier`: string (e.g. "63d75c6ba9ca3 | Insertion time: 1677155435696 | Customer ID: 12345 | Amount: -10") - `data[].account_id`: string (e.g. "12345") - `data[].time`: string (date-time; e.g. "2023-02-20T22:06:40.000Z") - `data[].timestamp`: integer (e.g. 1676930800) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Orders ### GET /merchants/{merchantId}/orders Returns merchant orders Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `total`: number - `data`: array of object - `data[].id`: number - `data[].uuid`: string - `data[].created_at`: string (date) - `data[].due_date`: string (date) - `data[].end_date`: string (date) - `data[].type`: string (one of: collection, delivery, fixed-delivery) - `data[].note`: string - `data[].delivery_address`: string - `data[].home_delivery_address`: string - `data[].status`: string (one of: accepted, pending, preparing, ready, complete, declibed) - `data[].basket`: object - `data[].basket.id`: number - `data[].basket.delivery_fee`: number - `data[].basket.service_charge`: number - `data[].basket.tax`: number - `data[].basket.tip`: number - `data[].basket.total`: number - `data[].basket.items`: array of object - `data[].basket.items[].id`: number - `data[].basket.items[].quantity`: number - `data[].basket.items[].categories_ids`: array of string - `data[].basket.items[].details`: object - `data[].branch`: object - `data[].branch.id`: number - `data[].branch.name`: string - `data[].clover`: object - `data[].clover.order_id`: string - `data[].customer`: object - `data[].customer.email`: string - `data[].customer.id`: number - `data[].customer.name`: string - `data[].customer.phone`: string - `data[].merchant`: object - `data[].merchant.id`: number - `data[].merchant.group_photo`: string - `data[].merchant.name`: string - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /merchants/{merchantId}/orders/v2 Returns Merchant Orders Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `total`: number - `summary`: object - `summary.avg_amount`: number - `summary.total_amount`: number - `summary.total_count`: number - `data`: array of object - `data[].id`: number - `data[].uuid`: string - `data[].created_at`: string (date) - `data[].due_date`: string (date) - `data[].end_date`: string (date) - `data[].type`: string (one of: collection, delivery, fixed-delivery) - `data[].note`: string - `data[].delivery_address`: string - `data[].home_delivery_address`: string - `data[].status`: string (one of: accepted, pending, preparing, ready, complete, declibed) - `data[].basket`: object - `data[].basket.id`: number - `data[].basket.delivery_fee`: number - `data[].basket.service_charge`: number - `data[].basket.tax`: number - `data[].basket.tip`: number - `data[].basket.total`: number - `data[].basket.items`: array of object - `data[].basket.items[].id`: number - `data[].basket.items[].quantity`: number - `data[].basket.items[].categories_ids`: array of string - `data[].basket.items[].details`: object - `data[].branch`: object - `data[].branch.id`: number - `data[].branch.name`: string - `data[].clover`: object - `data[].clover.order_id`: string - `data[].customer`: object - `data[].customer.email`: string - `data[].customer.id`: number - `data[].customer.name`: string - `data[].customer.phone`: string - `data[].merchant`: object - `data[].merchant.id`: number - `data[].merchant.group_photo`: string - `data[].merchant.name`: string - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /merchants/{merchantId}/orders/products Returns merchant order products Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `data`: array of object - `data[].id`: number - `data[].name`: string - `data[].price`: number - `data[].priceType`: string (one of: FIXED, variable) - `data[].quantity`: number - `data[].reward`: number - `data[].stampReward`: number - `data[].taxRateValue`: number - `data[].taxRates`: object - `data[].taxRates.elements`: array of object - `data[].taxRates.elements[].id`: number - `data[].taxRates.elements[].lineItemRef`: string - `data[].taxRates.elements[].name`: string - `data[].taxRates.elements[].rate`: number - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Reporting ### GET /merchants/{merchantId}/reports/gift-cards/liability/kpis Returns KPI data for gift cards liability report Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | franchise_id | query | integer | no | Filter by Franchise | | start_date | query | string (date-time) | no | Filter by date greater or equals than. In ISO 8601 format | | end_date | query | string (date-time) | no | Filter by date smaller or equals than. In ISO 8601 format | Responses: - 200: Successful operation - `summary`: object - `summary.credited`: object - `summary.credited.total`: integer (e.g. 375) - `summary.credited.volume`: integer (e.g. 4) - `summary.debited`: object - `summary.debited.total`: integer (e.g. 0) - `summary.debited.volume`: integer (e.g. 0) - `summary.expired`: object - `summary.expired.total`: integer (e.g. 0) - `summary.expired.volume`: integer (e.g. 0) - `summary.balance`: object - `summary.balance.total`: integer (e.g. 375) - `summary.balance.volume`: integer (e.g. 4) - 400: Invalid merchant id - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId}/reports/gift-cards/liability Returns merchant gift cards liability report data Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | franchise_id | query | integer | no | Filter by Franchise | | start_date | query | string (date-time) | no | Filter by date greater or equals than. In ISO 8601 format | | end_date | query | string (date-time) | no | Filter by date smaller or equals than. In ISO 8601 format | | order | query | string (one of: voucherNumber, voucherType, creditedBalance, creditedAt, creditedBranch, debitedBalance, debitedAt, debitedBranch, expiryDate, balance) | no | Field to be used for sorting the list | | direction | query | string (one of: asc, desc; default "desc") | no | Sorting direction | | exports_to | query | string (one of: csv) | no | Inform the format to export the data | Responses: - 200: Successful operation - `data`: array of object - `data[].userId`: integer (e.g. 142) - `data[].voucherNumber`: string (e.g. 402234773) - `data[].voucherType`: string (one of: physical, digital; e.g. "physical") - `data[].creditedBalance`: integer (e.g. 115) - `data[].creditedAt`: string (date-time; e.g. "2024-09-24T11:39:30.000Z") - `data[].creditedBranch`: string (e.g. "Branch Name") - `data[].debitedBalance`: integer - `data[].debitedAt`: string (date-time) - `data[].debitedBranch`: string - `data[].expiryDate`: string (date-time) - `data[].balance`: integer (e.g. 115) - `total`: integer (e.g. 49) - `totalPages`: integer (e.g. 5) - `currentPage`: integer (e.g. 1) - `perPage`: integer (e.g. 10) - 400: Invalid merchant id - 401: Invalid authentication - 500: Internal Server Error ## Gateway Reports ### GET /merchants/{merchantId}/reports/transactions Fetch transaction report from payment gateways Returns the merchant's card-terminal transactions from the merchant's payment gateway for a date range, merged with Facilipay stored-value redemptions, newest first. Read together with the batch report: the rules below are what reconcile the two. **Dates** are ISO 8601 instants in UTC and are the gateway's processing time of each transaction, not its settlement time. The range may not exceed 90 days. A batch settles transactions processed on earlier days, so the two reports do not line up by calendar date, and no batch reference or settlement date is exposed on a transaction. **Voids.** A voided sale is returned as `transactionType: SALE` with `status: VOID` and its original positive amount; the gateway has no separate void type. The batch report's `salesTotal` and `netAmount` exclude voided sales, so exclude `status: VOID` rows when reconciling against it. **Refunds** carry a negative `totalAmount`. The batch report's `refundsTotal` is the positive sum of the same rows. **Tips.** `amount.tipAmount` is the tip on that row as processed. The batch report's `tipsTotal` is the gateway's net tip after voids and refunds. **`transactionTypes`** is applied by the API after fetching, not by the gateway. `VOID` selects rows whose `status` is `VOID`; every other type selects non-voided rows of that type, so `SALE`, `REFUND` and `VOID` partition the gateway rows. A single value or an array is accepted. **AMEX.** Pass `includeAmex=false` to remove every transaction whose `cardBrand` is `AMEX`. Card brands are normalised before the filter runs, so every spelling the gateway uses for American Express is covered. The filter runs before paging, so `total`, `totalPages` and each page describe the non-AMEX set. Stored-value rows are never affected. `entryMode` and `authCode` are not provided by the payment gateway's transaction listing and are returned empty. A terminal whose gateway call fails is omitted rather than failing the request. All monetary values are in the smallest currency unit (e.g. cents). Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | startDate | query | string (date-time; e.g. "2026-01-01T00:00:00Z") | yes | Start date for the report (ISO 8601 format) | | endDate | query | string (date-time; e.g. "2026-01-31T23:59:59Z") | yes | End date for the report (ISO 8601 format) | | terminalIds | query | array of string | no | Filter by specific terminal IDs | | platformName | query | string | no | Filter by the terminal platform name configured for the merchant | | transactionTypes | query | array of string | no | Filter by transaction type, applied by the API after fetching. `VOID` matches rows whose status is `VOID` (a voided sale keeps type `SALE`); other values match non-voided rows of that type. A single value or an array is accepted. | | includeAmex | query | boolean (default true) | no | Include American Express transactions. `false` removes every row whose `cardBrand` is `AMEX` before paging, so `total` and each page describe the non-AMEX set. Accepted values are `true`, `false`, `1` and `0`; anything else is rejected. | | limit | query | integer (default 100; e.g. 50) | no | Maximum number of results per page (1-1000) | | offset | query | integer (default 0; e.g. 0) | no | Number of results to skip for pagination | Responses: - 200: Successful operation - `generatedAt`: string (date-time; e.g. "2026-01-20T10:00:00Z"). Report generation timestamp - `data`: array of object. Transactions matching the provided filters - `data[].transactionId`: string (e.g. "TXN-2026-001234"). Unique transaction ID from the gateway - `data[].orderId`: string (e.g. "ORD-5678"). Gateway-specific order/reference ID - `data[].terminalId`: string (e.g. "TERM001"). Terminal ID that processed the transaction - `data[].merchantId`: string (e.g. "253"). Merchant ID - `data[].gateway`: string. Payment provider identifier assigned by Facilipay; `stored_value` for Facilipay stored-value rows - `data[].platformName`: string. Terminal platform name from the merchant's configuration - `data[].transactionType`: string (one of: SALE, REFUND, VOID, PREAUTH, CAPTURE, OFFLINE; e.g. "SALE"). Transaction type - `data[].amount`: object. Detailed breakdown of transaction amount components. All amounts in smallest currency unit (e.g. cents). Only fields supported by the gateway are populated. - `data[].amount.totalAmount`: integer (e.g. 1350), required. Total transaction amount in cents - `data[].amount.tipAmount`: integer (e.g. 200). Tip amount in cents (if provided by gateway) - `data[].amount.taxAmount`: integer (e.g. 100). Tax amount in cents (if provided by gateway) - `data[].amount.cashbackAmount`: integer (e.g. 0). Cashback amount in cents (if provided by gateway) - `data[].amount.surchargeAmount`: integer (e.g. 50). Surcharge fee in cents (if provided by gateway) - `data[].amount.convenienceFeeAmount`: integer (e.g. 0). Convenience fee in cents (if provided by gateway) - `data[].amount.dualPricingAmount`: integer (e.g. 0). Dual pricing amount in cents (if provided by gateway) - `data[].currency`: string (e.g. "EUR"). Currency code (ISO 4217) - `data[].cardBrand`: string (one of: VISA, MASTERCARD, AMEX, DISCOVER, DINERS, JCB, UNIONPAY, FACILIPAY, UNKNOWN; e.g. "VISA"). Card brand - `data[].cardLast4`: string (e.g. "1234"). Last 4 digits of card - `data[].entryMode`: string (e.g. ""). Card entry mode. Not provided by the payment gateway's transaction listing; returned empty - `data[].status`: string (e.g. "READY"). Payment gateway status, passed through untouched (for example READY or VOID). A voided sale keeps transactionType SALE and reports VOID here - `data[].authCode`: string (e.g. ""). Authorization code. Not provided by the payment gateway's transaction listing; returned empty - `data[].transactionDate`: string (date-time; e.g. "2026-01-15T14:30:00Z"). Gateway processing timestamp, not the settlement time. No batch reference or settlement date is available on a transaction - `total`: integer (e.g. 150). Total number of results available - `totalPages`: integer (e.g. 3). Total number of pages - `currentPage`: integer (e.g. 1). Current page number (1-based) - `perPage`: integer (e.g. 50). Results per page - `truncated`: boolean (e.g. false). True when the gateway stopped returning pages before the window was fully read (page cap or a cursor that stopped advancing). Rows may then be missing and `total` may be low; narrow the date range and retry. - 400: Invalid parameters - 401: Invalid authentication - 404: Merchant not found - 500: Internal Server Error ### GET /merchants/{merchantId}/reports/batches Fetch batch report with settlement data Returns the merchant's closed card-terminal batches for a date range, merged with Facilipay stored-value redemptions (gift cards, prepaid, cashless). Each stored-value redemption is attached to the batch that was trading on its terminal at the time (the earliest batch submitted at or after it); redemptions that match no gateway batch are grouped into a synthetic `Facilipay` batch per terminal. Only redemptions dated inside the window are fetched, while batches are selected by settlement time, so a batch submitted before `startDate` and settled inside the window is listed without the redemptions it was trading before `startDate`, and a batch submitted inside the window but settled after `endDate` is not listed, its redemptions going to the next listed batch on the terminal or to the synthetic batch. Over a full read, `Σ batches[].netAmount = summary.netSalesTotal` and `Σ batches[].transactionCount = summary.gatewayTransactionCount + summary.storedValueRedemptionCount`. **Dates** are ISO 8601 instants in UTC. The range may not exceed 90 days. **Pagination.** Batches are sorted newest first by their reference time (`closedAt` when present, otherwise `openedAt`, which is the case while `IN_PROGRESS`) and paged with `limit` and `offset`. `total`, `totalPages` and `summary` describe the whole filtered set, so every page carries the same totals; an `offset` past the end returns an empty `batches` array with the full summary. **American Express** currently settles in its own batches, so a batch contains either only AMEX transactions or none at all; a batch is classified as AMEX by the card brand of its **first transaction**. The `summary` always breaks out those batches' totals as `gatewayAmexSalesTotal`, `gatewayAmexTipsTotal`, `gatewayAmexRefundsTotal`, `gatewayAmexVoidsTotal` and `gatewayAmexNetAmount`, so the non-AMEX settlement is `gatewayNetAmount − gatewayAmexNetAmount`. Pass `includeAmex=false` to omit AMEX batches from both `batches` and `summary`: the `gatewayAmex*` fields are then zero and the general `gateway*` fields are reduced by exactly the same amounts. Once AMEX settles together with other card brands, these fields are expected to be zero. **Transactions.** Every per-batch total and the report `summary` come from the gateway's own batch-level totals, not from the transactions array. Pass `includeTransactions=false` for a summary-only response that omits each batch's `transactions` array; totals are unaffected. When included, the array is complete for the batch. **Voids and net.** The gateway leaves voided sales out of `salesTotal` and `netAmount` and reports them only under `voidsTotal`, so voids are informational and are never subtracted again. Each batch's `netAmount` is the gateway's own settled figure and equals `salesTotal − refundsTotal`. `summary.gatewayNetAmount` is the sum of those per-batch figures; `summary.gatewayAmexNetAmount` is the AMEX share, so the non-AMEX settlement is `gatewayNetAmount − gatewayAmexNetAmount`. Tips are inside every net figure: subtract `tipsTotal` (or `gatewayTipsTotal` / `gatewayAmexTipsTotal`) to get the settlement excluding tips. A terminal whose gateway call fails is omitted from the response rather than failing the request. All monetary values are in the smallest currency unit (e.g. cents). Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | startDate | query | string (date-time; e.g. "2026-01-01T00:00:00Z") | yes | Start date for the report (ISO 8601 format) | | endDate | query | string (date-time; e.g. "2026-01-31T23:59:59Z") | yes | End date for the report (ISO 8601 format) | | terminalIds | query | array of string | no | Filter by specific terminal IDs | | platformName | query | string | no | Filter by the terminal platform name configured for the merchant | | includeLoyalty | query | boolean (default true) | no | Include stored value transactions (gift cards, prepaid, cashless) in the report | | loyaltyTypes | query | array of string | no | Filter stored value transactions by type | | includeAmex | query | boolean (default true) | no | Include American Express batches. AMEX currently settles separately, so `false` omits whole batches from both `batches` and `summary`; the `gatewayAmex*` summary fields are then zero and the general `gateway*` fields exclude those batches. A batch is an AMEX batch when its first transaction is AMEX. Accepted values are `true`, `false`, `1` and `0`; anything else is rejected. | | includeTransactions | query | boolean (default true) | no | Include each batch's `transactions` array. Pass `false` for a summary-only response; per-batch totals and `summary` are unchanged because they come from the gateway's batch-level totals. Accepted values are `true`, `false`, `1` and `0`; anything else is rejected. | | limit | query | integer (default 100; e.g. 50) | no | Maximum number of batches per page (1-1000) | | offset | query | integer (default 0; e.g. 0) | no | Number of batches to skip for pagination | Responses: - 200: Successful operation - `generatedAt`: string (date-time; e.g. "2026-01-20T10:00:00Z"). Report generation timestamp - `startDate`: string (date-time; e.g. "2026-01-01T00:00:00Z"). Report date range start - `endDate`: string (date-time; e.g. "2026-01-31T23:59:59Z"). Report date range end - `merchantId`: string (e.g. "253"). Merchant ID - `batches`: array of object. The current page of batches, newest first by reference time (closedAt when present, otherwise openedAt) - `batches[].batchId`: string (e.g. "BATCH-001"). Batch ID, the gateway's unique reference for the batch - `batches[].batchNumber`: string (e.g. "93"). The gateway's sequential batch number for the terminal, as printed on the terminal's settlement report. Absent on synthetic Facilipay batches - `batches[].terminalId`: string (e.g. "TERM001"). Terminal ID - `batches[].merchantId`: string (e.g. "253"). Merchant ID - `batches[].gateway`: string. Payment provider identifier assigned by Facilipay - `batches[].platformName`: string. Terminal platform name from the merchant's configuration; `Facilipay` for synthetic stored-value batches - `batches[].status`: string (one of: OPEN, CLOSED, IN_PROGRESS; e.g. "CLOSED"). Batch status. `IN_PROGRESS` is a gateway batch that has been submitted for settlement but has not completed; it has no `closedAt` yet. Synthetic Facilipay stored-value batches are never `IN_PROGRESS`. - `batches[].openedAt`: string (date-time; e.g. "2026-01-15T06:00:00Z"). When the terminal closed and submitted the batch (Worldnet dateTime). Not an open time: every transaction in the batch is dated at or before it. In-progress batches are selected and sorted by this value. A batch for which the gateway reported no such time carries 1970-01-01T00:00:00Z here. On a synthetic Facilipay stored-value batch this is the report's startDate, not a gateway event. Only a legacy-shape batch that reports an open time and no close time carries that open time here instead. - `batches[].closedAt`: string (date-time; e.g. "2026-01-15T22:00:00Z"). Settlement completion time. Batches are selected by this value when present (both window bounds inclusive), otherwise by openedAt. Absent while the batch is IN_PROGRESS. On a synthetic Facilipay stored-value batch this is the report's endDate, not a gateway event. - `batches[].transactionCount`: integer (e.g. 45). Number of transactions in batch - `batches[].salesTotal`: integer (e.g. 125000). Settled sales amount in cents, inclusive of tips. Voided sales are not included - `batches[].salesCount`: integer (e.g. 40). Number of sales - `batches[].refundsTotal`: integer (e.g. 5000). Total refunds amount in cents - `batches[].refundsCount`: integer (e.g. 5). Number of refunds - `batches[].voidsTotal`: integer (e.g. 2000). Total voided amount in batch (cents). Informational; voided sales are already excluded from salesTotal and netAmount - `batches[].voidsCount`: integer (e.g. 2). Number of voids - `batches[].declinesTotal`: integer (e.g. 3000). Gross declined amount in batch (cents, base + tip combined). These transactions never settled. - `batches[].declinesCount`: integer (e.g. 3). Number of declined transactions - `batches[].tipsTotal`: integer (e.g. 500). Total tip amount in batch (cents) - `batches[].netAmount`: integer (e.g. 120000). Net settled amount in cents, inclusive of tips. The gateway's own figure; equals salesTotal − refundsTotal (voided sales are already excluded from salesTotal) - `batches[].transactions`: array of object. Transactions in this batch. Present only when `includeTransactions` is true, and then complete for the batch (the gateway is paged until exhausted). Batch totals do not depend on this array. - `batches[].transactions[].transactionId`: string (e.g. "TXN-2026-001234"). Unique transaction ID from the gateway - `batches[].transactions[].orderId`: string (e.g. "ORD-5678"). Gateway-specific order/reference ID - `batches[].transactions[].terminalId`: string (e.g. "TERM001"). Terminal ID that processed the transaction - `batches[].transactions[].merchantId`: string (e.g. "253"). Merchant ID - `batches[].transactions[].gateway`: string. Payment provider identifier assigned by Facilipay; `stored_value` for Facilipay stored-value rows - `batches[].transactions[].platformName`: string. Terminal platform name from the merchant's configuration - `batches[].transactions[].transactionType`: string (one of: SALE, REFUND, VOID, PREAUTH, CAPTURE, OFFLINE; e.g. "SALE"). Transaction type - `batches[].transactions[].amount`: object. Detailed breakdown of transaction amount components. All amounts in smallest currency unit (e.g. cents). Only fields supported by the gateway are populated. - `batches[].transactions[].amount.totalAmount`: integer (e.g. 1350), required. Total transaction amount in cents - `batches[].transactions[].amount.tipAmount`: integer (e.g. 200). Tip amount in cents (if provided by gateway) - `batches[].transactions[].amount.taxAmount`: integer (e.g. 100). Tax amount in cents (if provided by gateway) - `batches[].transactions[].amount.cashbackAmount`: integer (e.g. 0). Cashback amount in cents (if provided by gateway) - `batches[].transactions[].amount.surchargeAmount`: integer (e.g. 50). Surcharge fee in cents (if provided by gateway) - `batches[].transactions[].amount.convenienceFeeAmount`: integer (e.g. 0). Convenience fee in cents (if provided by gateway) - `batches[].transactions[].amount.dualPricingAmount`: integer (e.g. 0). Dual pricing amount in cents (if provided by gateway) - `batches[].transactions[].currency`: string (e.g. "EUR"). Currency code (ISO 4217) - `batches[].transactions[].cardBrand`: string (one of: VISA, MASTERCARD, AMEX, DISCOVER, DINERS, JCB, UNIONPAY, FACILIPAY, UNKNOWN; e.g. "VISA"). Card brand - `batches[].transactions[].cardLast4`: string (e.g. "1234"). Last 4 digits of card - `batches[].transactions[].entryMode`: string (e.g. ""). Card entry mode. Not provided by the payment gateway's transaction listing; returned empty - `batches[].transactions[].status`: string (e.g. "READY"). Payment gateway status, passed through untouched (for example READY or VOID). A voided sale keeps transactionType SALE and reports VOID here - `batches[].transactions[].authCode`: string (e.g. ""). Authorization code. Not provided by the payment gateway's transaction listing; returned empty - `batches[].transactions[].transactionDate`: string (date-time; e.g. "2026-01-15T14:30:00Z"). Gateway processing timestamp, not the settlement time. No batch reference or settlement date is available on a transaction - `batches[].storedValueTransactions`: array of object. Stored value transactions during this batch period. Governed by `includeLoyalty`, not `includeTransactions`. - `batches[].storedValueTransactions[].transactionId`: string (e.g. "SV-001234"). Unique transaction identifier - `batches[].storedValueTransactions[].orderId`: string (e.g. "ORD-5678"). Associated order ID parsed from unique_identifier where available - `batches[].storedValueTransactions[].loyaltyType`: string (one of: gift, upfront, cashless, refund; e.g. "gift"). Stored value type - `batches[].storedValueTransactions[].terminalId`: string (e.g. "TERM001"). Terminal identifier from customer transactions - `batches[].storedValueTransactions[].cardBrand`: string (one of: VISA, MASTERCARD, AMEX, DISCOVER, DINERS, JCB, UNIONPAY, FACILIPAY, UNKNOWN; e.g. "UNKNOWN"). Payment brand for reporting harmonization - `batches[].storedValueTransactions[].amount`: object. Stored value amount payload currently returns totalAmount only - `batches[].storedValueTransactions[].amount.totalAmount`: integer (e.g. 500), required. Total transaction amount in cents - `batches[].storedValueTransactions[].balanceAfter`: integer (e.g. 1500). Balance after transaction in cents - `batches[].storedValueTransactions[].transactionDate`: string (date-time; e.g. "2026-01-15T14:35:00Z"). Transaction timestamp - `batches[].storedValueTransactions[].merchantId`: string (e.g. "253"). Merchant ID - `batches[].cardTypeSummary`: array of object. Per-card-type breakdown of settled totals. Present when the gateway provides summary data. - `batches[].cardTypeSummary[].cardType`: string (e.g. "Visa Debit"). Card type label as provided by the gateway (e.g. "Visa Debit", "MasterCard") - `batches[].cardTypeSummary[].currency`: string (e.g. "EUR"). ISO 4217 currency code - `batches[].cardTypeSummary[].netAmount`: integer (e.g. 50000). Net settled amount in cents, inclusive of tips. The gateway's own figure; equals salesTotal − refundsTotal (voided sales are already excluded from salesTotal) - `batches[].cardTypeSummary[].tipsTotal`: integer (e.g. 500). Settled tip component within netAmount in cents. netAmount - tipsTotal = base net. - `batches[].cardTypeSummary[].salesTotal`: integer (e.g. 55000). Settled sales amount in cents, inclusive of tips. Voided sales are not included - `batches[].cardTypeSummary[].salesCount`: integer (e.g. 20). Number of settled sales - `batches[].cardTypeSummary[].refundsTotal`: integer (e.g. 3000). Total refunded amount in cents - `batches[].cardTypeSummary[].refundsCount`: integer (e.g. 2). Number of refunds - `batches[].cardTypeSummary[].voidsTotal`: integer (e.g. 2000). Total voided amount in cents. Informational; voided sales are already excluded from salesTotal and netAmount - `batches[].cardTypeSummary[].voidsCount`: integer (e.g. 1). Number of voids - `batches[].cardTypeSummary[].declinesTotal`: integer (e.g. 1000). Gross declined amount in cents (base + tip combined). Never settled — excluded from netAmount. - `batches[].cardTypeSummary[].declinesCount`: integer (e.g. 1). Number of declined transactions - `batches[].cardTypeSummary[].transactionCount`: integer (e.g. 24). Total transaction count (sales + refunds + voids + declines) - `summary`: object. Summary totals over the whole filtered set (all pages). Every gateway figure is a sum of the gateway's own batch-level totals, never of the transactions arrays. - `summary.batchCount`: integer (e.g. 5). Total number of batches across all pages, including synthetic Facilipay batches - `summary.gatewayTransactionCount`: integer (e.g. 225). Total gateway transactions (sales + refunds + voids + declines) - `summary.gatewaySalesTotal`: integer (e.g. 625000). Total gateway sales in cents, inclusive of tips. Voided sales are not included - `summary.gatewayTipsTotal`: integer (e.g. 5000). Total gateway tips from batch-level gateway totals in cents - `summary.gatewayRefundsTotal`: integer (e.g. 25000). Total gateway refunds in cents - `summary.gatewayVoidsTotal`: integer (e.g. 10000). Total gateway voids in cents - `summary.gatewayVoidsCount`: integer (e.g. 4). Number of gateway voids - `summary.gatewayNetAmount`: integer (e.g. 600000). Sum of each batch's gateway-reported netAmount, in cents. Equals gatewaySalesTotal − gatewayRefundsTotal; voids are not subtracted because they are already excluded from sales - `summary.gatewayAmexSalesTotal`: integer (e.g. 125000). Summed salesTotal in cents of the batches classified as AMEX by their first transaction. Zero when includeAmex is false. - `summary.gatewayAmexTipsTotal`: integer (e.g. 1000). Summed tipsTotal in cents of the AMEX batches. Zero when includeAmex is false. - `summary.gatewayAmexRefundsTotal`: integer (e.g. 5000). Summed refundsTotal in cents of the AMEX batches. Zero when includeAmex is false. - `summary.gatewayAmexVoidsTotal`: integer (e.g. 2000). Summed voidsTotal in cents of the AMEX batches. Zero when includeAmex is false. - `summary.gatewayAmexNetAmount`: integer (e.g. 120000). Summed netAmount in cents of the AMEX batches. The non-AMEX settlement is gatewayNetAmount − gatewayAmexNetAmount. Zero when includeAmex is false. - `summary.storedValueRedemptionCount`: integer (e.g. 30). Total stored value redemptions - `summary.storedValueRedemptionTotal`: integer (e.g. 15000). Total stored value redemption amount in cents - `summary.netSalesTotal`: integer (e.g. 615000). Combined net sales (gatewayNetAmount + storedValueRedemptionTotal) in cents - `total`: integer (e.g. 150). Total number of batches matching the filters, across all pages - `totalPages`: integer (e.g. 3). Total number of pages - `currentPage`: integer (e.g. 1). Current page number (1-based) - `perPage`: integer (e.g. 50). Batches per page - `truncated`: boolean (e.g. false). True when the gateway's batch listing, or the transaction fetch for a batch on this page, stopped before being fully read (page cap or a cursor that stopped advancing). Batches, `summary` and `total` may then be incomplete; narrow the date range and retry. - 400: Invalid parameters - 401: Invalid authentication - 404: Merchant not found - 500: Internal Server Error # Inventory ## Products ### GET /inventory/products Returns a list of Merchant's Inventory Products Authentication (any one): authorization (header `authorization`). Responses: - 200: Successful operation - `total`: number (e.g. 282) - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].external_code`: string (e.g. "SDTX6S4750DZW") - `data[].name`: string (e.g. "Guinness") - `data[].image`: string (default null; e.g. "https://ucarecdn.com/736337f8-91ad-420b-ab2a-a873da81c828/") - `data[].base_price`: number (int64; e.g. 290) - `data[].branch_id`: number (e.g. 2557) - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].order`: number (int64; e.g. 2) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].stamp_reward`: number (e.g. 1) - `data[].reward`: string (default null; e.g. "this is a reward") - `data[].price_type`: string (e.g. "FIXED") - `data[].unit_name`: string (e.g. "weds") - `data[].stock_count`: number (e.g. 1) - `data[].limit_stock_value`: number (e.g. 1) - `data[].limit_stock`: boolean (e.g. false) - `data[].collection`: boolean (e.g. true) - `data[].fixed_delivery`: boolean (e.g. false) - `data[].delivery`: boolean (e.g. true) - `data[].allergens`: array of object - `data[].allergens[].id`: number (e.g. 1) - `data[].allergens[].name`: string (e.g. "cereals containing gluten") - `data[].categories_ids`: array of number - `data[].categories`: array of object - `data[].categories[].id`: number (e.g. 1) - `data[].categories[].name`: string (e.g. "Smaller Portions") - `data[].categories[].image`: string (default null) - `data[].modifier_groups`: array of object - `data[].modifier_groups[].id`: number (e.g. 1) - `data[].modifier_groups[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].image`: string (default null) - `data[].modifier_groups[].max_allowed`: number (e.g. 3) - `data[].modifier_groups[].min_required`: number (e.g. 3) - `data[].modifier_groups[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].order`: number (e.g. 1) - `data[].modifier_groups[].modifiers`: array of object - `data[].modifier_groups[].modifiers[].id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].modifiers[].price`: number (e.g. 9.99) - `data[].modifier_groups[].modifiers[].image`: string (default null) - `data[].modifier_groups[].modifiers[].status`: string (one of: 0, 1) - `data[].modifier_groups[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifier_groups[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].order`: number (e.g. 4) - `data[].modifier_groups[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifier_groups[].modifiers[].group_id`: number (e.g. 108) - `data[].modifier_groups[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifier_groups[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].tax_rates`: array of object - `data[].modifier_groups[].tax_rates[].id`: number (e.g. 49675214) - `data[].modifier_groups[].tax_rates[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].tax_rates[].name`: string (e.g. "VAT") - `data[].modifier_groups[].tax_rates[].is_default`: string (one of: 0, 1) - `data[].modifier_groups[].tax_rates[].rate`: number (e.g. 2300000) - 400: Invalid merchant id - 401: Unauthorized - 404: not found ### POST /inventory/products Creates an inventory product Authentication (any one): authorization (header `authorization`). Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `item_data`: object - `item_data.name`: string - `item_data.description`: string - `item_data.base_price`: number - `item_data.categories_ids`: array of number - `item_data.availability`: object - `item_data.availability.day`: string (e.g. "Friday") - `item_data.availability.from`: string (e.g. "00:00") - `item_data.availability.to`: string (e.g. "23:59") - `item_data.availability.isOpen`: boolean - `item_data.allergens`: array of number - `item_data.unavailable_for_order_ahead`: boolean - `item_data.unavailable_for_self_checkout`: boolean - `item_data.stamp_reward`: number (e.g. 0) - `item_data.reward`: number (e.g. 1) - `item_data.stock_count`: number (e.g. 4) - `item_data.limit_stock_value`: number (e.g. 7) - `item_data.limit_stock`: boolean - `item_data.collection`: boolean - `item_data.fixed_delivery`: boolean - `item_data.delivery`: boolean - `item_data.tax_rates`: object - `item_data.tax_rates.external_id`: string (default null) - `item_data.tax_rates.id`: integer - `item_data.tax_rates.is_default`: boolean - `item_data.tax_rates.name`: string - `item_data.tax_rates.rate`: number (e.g. 2300000) Responses: - 200: Successful operation - `id`: number - `name`: string (e.g. "Product name") - `description`: string (e.g. "Product Description") - `base_price`: number (e.g. 3333) - `unavailable_for_order_ahead`: boolean - `unavailable_for_self_checkout`: boolean - `reward`: number (e.g. 20) - `stamp_reward`: number (e.g. 0) - `group_id`: string (e.g. "108") - `branch_id`: number (e.g. 5309) - `stock_count`: number (e.g. 2) - `status`: integer (one of: 0, 1) - `updatedAt`: string (date) - `createdAt`: string (date) - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /inventory/products/{productId} Returns a product details Returns a specific product details Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | productId | path | integer (int64; e.g. 253) | yes | ID of product | Responses: - 200: Successful operation - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].external_code`: string (e.g. "SDTX6S4750DZW") - `data[].name`: string (e.g. "Guinness") - `data[].image`: string (default null; e.g. "https://ucarecdn.com/736337f8-91ad-420b-ab2a-a873da81c828/") - `data[].base_price`: number (int64; e.g. 290) - `data[].branch_id`: number (e.g. 2557) - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].order`: number (int64; e.g. 2) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].stamp_reward`: number (e.g. 1) - `data[].reward`: string (default null; e.g. "this is a reward") - `data[].price_type`: string (e.g. "FIXED") - `data[].unit_name`: string (e.g. "weds") - `data[].stock_count`: number (e.g. 1) - `data[].limit_stock_value`: number (e.g. 1) - `data[].limit_stock`: boolean (e.g. false) - `data[].collection`: boolean (e.g. true) - `data[].fixed_delivery`: boolean (e.g. false) - `data[].delivery`: boolean (e.g. true) - `data[].allergens`: array of object - `data[].allergens[].id`: number (e.g. 1) - `data[].allergens[].name`: string (e.g. "cereals containing gluten") - `data[].categories_ids`: array of number - `data[].categories`: array of object - `data[].categories[].id`: number (e.g. 1) - `data[].categories[].name`: string (e.g. "Smaller Portions") - `data[].categories[].image`: string (default null) - `data[].modifier_groups`: array of object - `data[].modifier_groups[].id`: number (e.g. 1) - `data[].modifier_groups[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].image`: string (default null) - `data[].modifier_groups[].max_allowed`: number (e.g. 3) - `data[].modifier_groups[].min_required`: number (e.g. 3) - `data[].modifier_groups[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].order`: number (e.g. 1) - `data[].modifier_groups[].modifiers`: array of object - `data[].modifier_groups[].modifiers[].id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].modifiers[].price`: number (e.g. 9.99) - `data[].modifier_groups[].modifiers[].image`: string (default null) - `data[].modifier_groups[].modifiers[].status`: string (one of: 0, 1) - `data[].modifier_groups[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifier_groups[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].order`: number (e.g. 4) - `data[].modifier_groups[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifier_groups[].modifiers[].group_id`: number (e.g. 108) - `data[].modifier_groups[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifier_groups[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].tax_rates`: array of object - `data[].modifier_groups[].tax_rates[].id`: number (e.g. 49675214) - `data[].modifier_groups[].tax_rates[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].tax_rates[].name`: string (e.g. "VAT") - `data[].modifier_groups[].tax_rates[].is_default`: string (one of: 0, 1) - `data[].modifier_groups[].tax_rates[].rate`: number (e.g. 2300000) - `total`: number (e.g. 1) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /inventory/products/{productId} Updates a product Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | productId | path | integer (int64; e.g. 253) | yes | ID of product | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `item_data`: object - `item_data.name`: string - `item_data.description`: string - `item_data.base_price`: number - `item_data.categories_ids`: array of number - `item_data.availability`: object - `item_data.availability.day`: string (e.g. "Friday") - `item_data.availability.from`: string (e.g. "00:00") - `item_data.availability.to`: string (e.g. "23:59") - `item_data.availability.isOpen`: boolean - `item_data.allergens`: array of number - `item_data.unavailable_for_order_ahead`: boolean - `item_data.unavailable_for_self_checkout`: boolean - `item_data.stamp_reward`: number (e.g. 0) - `item_data.reward`: number (e.g. 1) - `item_data.stock_count`: number (e.g. 4) - `item_data.limit_stock_value`: number (e.g. 7) - `item_data.limit_stock`: boolean - `item_data.collection`: boolean - `item_data.fixed_delivery`: boolean - `item_data.delivery`: boolean - `item_data.tax_rates`: object - `item_data.tax_rates.external_id`: string (default null) - `item_data.tax_rates.id`: integer - `item_data.tax_rates.is_default`: boolean - `item_data.tax_rates.name`: string - `item_data.tax_rates.rate`: number (e.g. 2300000) Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /inventory/products/{productId}/image Update image of a product Updates image on a specific product Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | productId | path | integer (int64; e.g. 253) | yes | ID of product | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - `message`: string (e.g. "Updated product image") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /inventory/products/{productId}/image Deletes image of a category Deletes image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | productId | path | integer (int64; e.g. 253) | yes | ID of product | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Categories ### GET /inventory/categories Returns a list of Merchant's Inventory Categories Authentication (any one): authorization (header `authorization`). Responses: - 200: Successful operation - `total`: number (e.g. 282) - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].name`: string (e.g. "Beverages") - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].branch_id`: integer (int64; default null) - `data[].image`: string (default null; e.g. "image url") - `data[].order`: number (int64; e.g. 2) - `data[].status`: boolean (e.g. true) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].availability`: array of object - `data[].availability[].day`: string (e.g. "Sunday") - `data[].availability[].from`: string (e.g. "00:00") - `data[].availability[].to`: string (e.g. "23:59") - `data[].availability[].isOpen`: boolean (e.g. true) - `data[].products_total`: number (e.g. 2) - 400: Invalid merchant id - 401: Unauthorized - 404: not found ### POST /inventory/categories Updates a category Authentication (any one): authorization (header `authorization`). Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `category_data`: object - `category_data.name`: string - `category_data.order`: number (e.g. 1) - `category_data.availability`: object - `category_data.availability.day`: string (e.g. "Friday") - `category_data.availability.from`: string (e.g. "00:00") - `category_data.availability.to`: string (e.g. "23:59") - `category_data.availability.isOpen`: boolean - `category_data.unavailable_for_order_ahead`: boolean - `category_data.unavailable_for_self_checkout`: boolean Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /inventory/categories/{categoryId} Returns a categoty details Returns a specific category details Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Responses: - 200: Successful operation - `id`: number (int64; e.g. 217) - `name`: string (e.g. "Beverages") - `description`: string (default null; e.g. "this is a description") - `created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `branch_id`: integer (int64; default null) - `image`: string (default null; e.g. "image url") - `order`: number (int64; e.g. 2) - `status`: boolean (e.g. true) - `unavailable_for_order_ahead`: boolean (e.g. true) - `unavailable_for_self_checkout`: boolean (e.g. true) - `availability`: array of object - `availability[].day`: string (e.g. "Sunday") - `availability[].from`: string (e.g. "00:00") - `availability[].to`: string (e.g. "23:59") - `availability[].isOpen`: boolean (e.g. true) - `products_total`: number (e.g. 2) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /inventory/categories/{categoryId} Updates a category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `category_data`: object - `category_data.name`: string - `category_data.order`: number (e.g. 1) - `category_data.availability`: object - `category_data.availability.day`: string (e.g. "Friday") - `category_data.availability.from`: string (e.g. "00:00") - `category_data.availability.to`: string (e.g. "23:59") - `category_data.availability.isOpen`: boolean - `category_data.unavailable_for_order_ahead`: boolean - `category_data.unavailable_for_self_checkout`: boolean Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /inventory/categories/{categoryId}/image Update image of a category Updates image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /inventory/categories/{categoryId}/image Deletes image of a category Deletes image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /inventory/categories/{categoryId}/products Returns products from a category Returns a list o products related to a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Responses: - 200: Successful operation - `id`: integer - `name`: string - `inventory_products`: array of object - `inventory_products[].id`: number (int64; e.g. 217) - `inventory_products[].base_price`: number (int64; e.g. 290) - `inventory_products[].name`: string (e.g. "Guinness") - `inventory_products[].unavailable_for_order_ahead`: boolean (e.g. true) - `inventory_products[].inventory_categories_products`: object - `inventory_products[].inventory_categories_products.category_id`: integer (int64) - `inventory_products[].inventory_categories_products.id`: integer (int64) - `inventory_products[].inventory_categories_products.product_id`: integer (int64) - `inventory_products[].inventory_categories_products.unavailable_for_order_ahead`: boolean (e.g. true) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /inventory/categories/{categoryId}/products Update products from a category Updates products on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | categoryId | path | integer (int64; e.g. 253) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `ordering`: array of number Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Modifier Groups ### GET /inventory/modifiers-groups Returns modifier groups Returns a list of modifier groups Authentication (any one): authorization (header `authorization`). Responses: - 200: Successful operation - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].name`: string (e.g. "Add Toast & Jam") - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].group_id`: number (e.g. 108) - `data[].status`: string (one of: 0, 1) - `data[].max_allowed`: number (e.g. 3) - `data[].min_required`: number (e.g. 3) - `data[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifiers`: array of object - `data[].modifiers[].id`: number (e.g. 1) - `data[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifiers[].price`: number (e.g. 9.99) - `data[].modifiers[].image`: string (default null) - `data[].modifiers[].status`: string (one of: 0, 1) - `data[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifiers[].order`: number (e.g. 4) - `data[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifiers[].group_id`: number (e.g. 108) - `data[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `total`: number (e.g. 574) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### POST /inventory/modifiers-groups creates a new modifier group Authentication (any one): authorization (header `authorization`). Request body (application/json): - `name`: string, required - `branch_id`: integer (int64; e.g. 4219), required - `order`: number - `max_allowed`: number (default null) - `min_required`: number (default null) - `modifiers`: array of object - `modifiers[].external_id`: string (default null) - `modifiers[].hidden`: boolean - `modifiers[].id`: integer (int64) - `modifiers[].name`: string - `modifiers[].oder`: number - `modifiers[].price`: number - `modifiers[].status`: integer (one of: 0, 1) Responses: - 200: Successful operation - `id`: number - `name`: string - `max_allowed`: number - `min_required`: number - `order`: number - `branch_id`: number - `status`: integer (one of: 0, 1) - `group_id`: string - `updatedAt`: string - `createdAt`: string (date) - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /inventory/modifiers-groups/{modifiersGroupId} Returns a modifier group Returns a specific modifier group Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - `branch_id`: number - `updatedAt`: string (date) - `createdAt`: string (date) - `external_id`: string - `group_id`: number - `id`: number - `image`: string - `max_allowed`: string - `min_required`: string - `name`: string - `order`: number - `status`: string - `modifiers`: array of object - `modifiers[].id`: number (e.g. 1) - `modifiers[].name`: string (e.g. "PORTIONS") - `modifiers[].price`: number (e.g. 9.99) - `modifiers[].image`: string (default null) - `modifiers[].status`: string (one of: 0, 1) - `modifiers[].description`: string (default null; e.g. "this is a description") - `modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `modifiers[].modifier_group_id`: number (e.g. 1) - `modifiers[].order`: number (e.g. 4) - `modifiers[].hidden`: boolean (e.g. false) - `modifiers[].group_id`: number (e.g. 108) - `modifiers[].branch_id`: number (e.g. 2534) - `modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /inventory/modifiers-groups/{modifiersGroupId} Updates a modifier group Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `name`: string - `order`: number - `max_allowed`: number - `min_required`: number - `modifiers`: array of object - `modifiers[].id`: number (e.g. 1) - `modifiers[].name`: string (e.g. "PORTIONS") - `modifiers[].price`: number (e.g. 9.99) - `modifiers[].image`: string (default null) - `modifiers[].status`: string (one of: 0, 1) - `modifiers[].description`: string (default null; e.g. "this is a description") - `modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `modifiers[].modifier_group_id`: number (e.g. 1) - `modifiers[].order`: number (e.g. 4) - `modifiers[].hidden`: boolean (e.g. false) - `modifiers[].group_id`: number (e.g. 108) - `modifiers[].branch_id`: number (e.g. 2534) - `modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /inventory/modifiers-groups/{modifiersGroupId}/image Updates a modifier group image Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /inventory/modifiers-groups/{modifiersGroupId}/image Deletes a modifier group image Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /inventory/modifiers-groups/{modifiersGroupId}/products Returns a modifier group with its associated products Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - `branch_id`: number - `group_id`: number - `id`: number - `name`: string - `inventory_products`: array of object - `inventory_products[].id`: number - `inventory_products[].name`: string - `inventory_products[].base_price`: number - `inventory_products[].tax_included`: integer (one of: 0, 1) - `inventory_products[].image`: string - `inventory_products[].status`: string (one of: 0, 1) - `inventory_products[].description`: string - `inventory_products[].price_type`: string - `inventory_products[].unit_name`: string - `inventory_products[].external_id`: string - `inventory_products[].external_code`: string - `inventory_products[].stock_count`: number - `inventory_products[].branch_id`: number - `inventory_products[].group_id`: number - `inventory_products[].order`: number - `inventory_products[].unavailable_for_order_ahead`: integer (one of: 0, 1) - `inventory_products[].unavailable_for_self_checkout`: integer (one of: 0, 1) - `inventory_products[].stamp_reward`: number - `inventory_products[].reward`: number - `inventory_products[].limit_stock_value`: number - `inventory_products[].limit_stock`: number - `inventory_products[].delivery`: integer (one of: 0, 1) - `inventory_products[].fixed_delivery`: integer (one of: 0, 1) - `inventory_products[].collection`: integer (one of: 0, 1) - `inventory_products[].createdAt`: string (date) - `inventory_products[].updatedAt`: string (date) - `inventory_products[].created_at`: string (date) - `inventory_products[].updated_at`: string (date) - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.id`: number - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.modifier_group_id`: number - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.product_id`: number - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /inventory/modifiers-groups/{modifiersGroupId}/products Returns a modifier group with its associated products Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `products`: array of number Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Products (by merchant ID) ### GET /merchants/{merchantId}/inventory/products Returns a list of Merchant's Inventory Products Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `total`: number (e.g. 282) - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].external_code`: string (e.g. "SDTX6S4750DZW") - `data[].name`: string (e.g. "Guinness") - `data[].image`: string (default null; e.g. "https://ucarecdn.com/736337f8-91ad-420b-ab2a-a873da81c828/") - `data[].base_price`: number (int64; e.g. 290) - `data[].branch_id`: number (e.g. 2557) - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].order`: number (int64; e.g. 2) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].stamp_reward`: number (e.g. 1) - `data[].reward`: string (default null; e.g. "this is a reward") - `data[].price_type`: string (e.g. "FIXED") - `data[].unit_name`: string (e.g. "weds") - `data[].stock_count`: number (e.g. 1) - `data[].limit_stock_value`: number (e.g. 1) - `data[].limit_stock`: boolean (e.g. false) - `data[].collection`: boolean (e.g. true) - `data[].fixed_delivery`: boolean (e.g. false) - `data[].delivery`: boolean (e.g. true) - `data[].allergens`: array of object - `data[].allergens[].id`: number (e.g. 1) - `data[].allergens[].name`: string (e.g. "cereals containing gluten") - `data[].categories_ids`: array of number - `data[].categories`: array of object - `data[].categories[].id`: number (e.g. 1) - `data[].categories[].name`: string (e.g. "Smaller Portions") - `data[].categories[].image`: string (default null) - `data[].modifier_groups`: array of object - `data[].modifier_groups[].id`: number (e.g. 1) - `data[].modifier_groups[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].image`: string (default null) - `data[].modifier_groups[].max_allowed`: number (e.g. 3) - `data[].modifier_groups[].min_required`: number (e.g. 3) - `data[].modifier_groups[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].order`: number (e.g. 1) - `data[].modifier_groups[].modifiers`: array of object - `data[].modifier_groups[].modifiers[].id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].modifiers[].price`: number (e.g. 9.99) - `data[].modifier_groups[].modifiers[].image`: string (default null) - `data[].modifier_groups[].modifiers[].status`: string (one of: 0, 1) - `data[].modifier_groups[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifier_groups[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].order`: number (e.g. 4) - `data[].modifier_groups[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifier_groups[].modifiers[].group_id`: number (e.g. 108) - `data[].modifier_groups[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifier_groups[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].tax_rates`: array of object - `data[].modifier_groups[].tax_rates[].id`: number (e.g. 49675214) - `data[].modifier_groups[].tax_rates[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].tax_rates[].name`: string (e.g. "VAT") - `data[].modifier_groups[].tax_rates[].is_default`: string (one of: 0, 1) - `data[].modifier_groups[].tax_rates[].rate`: number (e.g. 2300000) - 400: Invalid merchant id - 404: Merchant not found ### POST /merchants/{merchantId}/inventory/products Creates an inventory product Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `item_data`: object - `item_data.name`: string - `item_data.description`: string - `item_data.base_price`: number - `item_data.categories_ids`: array of number - `item_data.availability`: object - `item_data.availability.day`: string (e.g. "Friday") - `item_data.availability.from`: string (e.g. "00:00") - `item_data.availability.to`: string (e.g. "23:59") - `item_data.availability.isOpen`: boolean - `item_data.allergens`: array of number - `item_data.unavailable_for_order_ahead`: boolean - `item_data.unavailable_for_self_checkout`: boolean - `item_data.stamp_reward`: number (e.g. 0) - `item_data.reward`: number (e.g. 1) - `item_data.stock_count`: number (e.g. 4) - `item_data.limit_stock_value`: number (e.g. 7) - `item_data.limit_stock`: boolean - `item_data.collection`: boolean - `item_data.fixed_delivery`: boolean - `item_data.delivery`: boolean - `item_data.tax_rates`: object - `item_data.tax_rates.external_id`: string (default null) - `item_data.tax_rates.id`: integer - `item_data.tax_rates.is_default`: boolean - `item_data.tax_rates.name`: string - `item_data.tax_rates.rate`: number (e.g. 2300000) Responses: - 200: Successful operation - `id`: number - `name`: string (e.g. "Product name") - `description`: string (e.g. "Product Description") - `base_price`: number (e.g. 3333) - `unavailable_for_order_ahead`: boolean - `unavailable_for_self_checkout`: boolean - `reward`: number (e.g. 20) - `stamp_reward`: number (e.g. 0) - `group_id`: string (e.g. "108") - `branch_id`: number (e.g. 5309) - `stock_count`: number (e.g. 2) - `status`: integer (one of: 0, 1) - `updatedAt`: string (date) - `createdAt`: string (date) - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId}/inventory/products/{productId} Returns a product details Returns a specific product details Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | productId | path | integer (int64; e.g. 26867041) | yes | ID of product | Responses: - 200: Successful operation - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].external_code`: string (e.g. "SDTX6S4750DZW") - `data[].name`: string (e.g. "Guinness") - `data[].image`: string (default null; e.g. "https://ucarecdn.com/736337f8-91ad-420b-ab2a-a873da81c828/") - `data[].base_price`: number (int64; e.g. 290) - `data[].branch_id`: number (e.g. 2557) - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].order`: number (int64; e.g. 2) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].stamp_reward`: number (e.g. 1) - `data[].reward`: string (default null; e.g. "this is a reward") - `data[].price_type`: string (e.g. "FIXED") - `data[].unit_name`: string (e.g. "weds") - `data[].stock_count`: number (e.g. 1) - `data[].limit_stock_value`: number (e.g. 1) - `data[].limit_stock`: boolean (e.g. false) - `data[].collection`: boolean (e.g. true) - `data[].fixed_delivery`: boolean (e.g. false) - `data[].delivery`: boolean (e.g. true) - `data[].allergens`: array of object - `data[].allergens[].id`: number (e.g. 1) - `data[].allergens[].name`: string (e.g. "cereals containing gluten") - `data[].categories_ids`: array of number - `data[].categories`: array of object - `data[].categories[].id`: number (e.g. 1) - `data[].categories[].name`: string (e.g. "Smaller Portions") - `data[].categories[].image`: string (default null) - `data[].modifier_groups`: array of object - `data[].modifier_groups[].id`: number (e.g. 1) - `data[].modifier_groups[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].image`: string (default null) - `data[].modifier_groups[].max_allowed`: number (e.g. 3) - `data[].modifier_groups[].min_required`: number (e.g. 3) - `data[].modifier_groups[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].order`: number (e.g. 1) - `data[].modifier_groups[].modifiers`: array of object - `data[].modifier_groups[].modifiers[].id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifier_groups[].modifiers[].price`: number (e.g. 9.99) - `data[].modifier_groups[].modifiers[].image`: string (default null) - `data[].modifier_groups[].modifiers[].status`: string (one of: 0, 1) - `data[].modifier_groups[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifier_groups[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifier_groups[].modifiers[].order`: number (e.g. 4) - `data[].modifier_groups[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifier_groups[].modifiers[].group_id`: number (e.g. 108) - `data[].modifier_groups[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifier_groups[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifier_groups[].tax_rates`: array of object - `data[].modifier_groups[].tax_rates[].id`: number (e.g. 49675214) - `data[].modifier_groups[].tax_rates[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifier_groups[].tax_rates[].name`: string (e.g. "VAT") - `data[].modifier_groups[].tax_rates[].is_default`: string (one of: 0, 1) - `data[].modifier_groups[].tax_rates[].rate`: number (e.g. 2300000) - `total`: number (e.g. 1) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /merchants/{merchantId}/inventory/products/{productId} Updates a product Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | productId | path | integer (int64; e.g. 26867041) | yes | ID of product | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `item_data`: object - `item_data.name`: string - `item_data.description`: string - `item_data.base_price`: number - `item_data.categories_ids`: array of number - `item_data.availability`: object - `item_data.availability.day`: string (e.g. "Friday") - `item_data.availability.from`: string (e.g. "00:00") - `item_data.availability.to`: string (e.g. "23:59") - `item_data.availability.isOpen`: boolean - `item_data.allergens`: array of number - `item_data.unavailable_for_order_ahead`: boolean - `item_data.unavailable_for_self_checkout`: boolean - `item_data.stamp_reward`: number (e.g. 0) - `item_data.reward`: number (e.g. 1) - `item_data.stock_count`: number (e.g. 4) - `item_data.limit_stock_value`: number (e.g. 7) - `item_data.limit_stock`: boolean - `item_data.collection`: boolean - `item_data.fixed_delivery`: boolean - `item_data.delivery`: boolean - `item_data.tax_rates`: object - `item_data.tax_rates.external_id`: string (default null) - `item_data.tax_rates.id`: integer - `item_data.tax_rates.is_default`: boolean - `item_data.tax_rates.name`: string - `item_data.tax_rates.rate`: number (e.g. 2300000) Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /merchants/{merchantId}/inventory/products/{productId}/image Update image of a product Updates image on a specific product Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - `message`: string (e.g. "Updated product image") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /merchants/{merchantId}/inventory/products/{productId}/image Deletes image of a category Deletes image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Categories (by merchant ID) ### GET /merchants/{merchantId}/inventory/categories Returns a list of Merchant's Inventory Categories Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `total`: number (e.g. 282) - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].name`: string (e.g. "Beverages") - `data[].description`: string (default null; e.g. "this is a description") - `data[].created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].branch_id`: integer (int64; default null) - `data[].image`: string (default null; e.g. "image url") - `data[].order`: number (int64; e.g. 2) - `data[].status`: boolean (e.g. true) - `data[].unavailable_for_order_ahead`: boolean (e.g. true) - `data[].unavailable_for_self_checkout`: boolean (e.g. true) - `data[].availability`: array of object - `data[].availability[].day`: string (e.g. "Sunday") - `data[].availability[].from`: string (e.g. "00:00") - `data[].availability[].to`: string (e.g. "23:59") - `data[].availability[].isOpen`: boolean (e.g. true) - `data[].products_total`: number (e.g. 2) - 400: Invalid merchant id - 404: Merchant not found ### POST /merchants/{merchantId}/inventory/categories Updates a category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `category_data`: object - `category_data.name`: string - `category_data.order`: number (e.g. 1) - `category_data.availability`: object - `category_data.availability.day`: string (e.g. "Friday") - `category_data.availability.from`: string (e.g. "00:00") - `category_data.availability.to`: string (e.g. "23:59") - `category_data.availability.isOpen`: boolean - `category_data.unavailable_for_order_ahead`: boolean - `category_data.unavailable_for_self_checkout`: boolean Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId}/inventory/categories/{categoryId} Returns a Categoty details Returns a specific category details Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Responses: - 200: Successful operation - `id`: number (int64; e.g. 217) - `name`: string (e.g. "Beverages") - `description`: string (default null; e.g. "this is a description") - `created_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `updated_at`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `branch_id`: integer (int64; default null) - `image`: string (default null; e.g. "image url") - `order`: number (int64; e.g. 2) - `status`: boolean (e.g. true) - `unavailable_for_order_ahead`: boolean (e.g. true) - `unavailable_for_self_checkout`: boolean (e.g. true) - `availability`: array of object - `availability[].day`: string (e.g. "Sunday") - `availability[].from`: string (e.g. "00:00") - `availability[].to`: string (e.g. "23:59") - `availability[].isOpen`: boolean (e.g. true) - `products_total`: number (e.g. 2) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /merchants/{merchantId}/inventory/categories/{categoryId} Updates a category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `branch_id`: integer (int64; e.g. 4219) - `category_data`: object - `category_data.name`: string - `category_data.order`: number (e.g. 1) - `category_data.availability`: object - `category_data.availability.day`: string (e.g. "Friday") - `category_data.availability.from`: string (e.g. "00:00") - `category_data.availability.to`: string (e.g. "23:59") - `category_data.availability.isOpen`: boolean - `category_data.unavailable_for_order_ahead`: boolean - `category_data.unavailable_for_self_checkout`: boolean Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /merchants/{merchantId}/inventory/categories/{categoryId}/image Update image of a category Updates image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /merchants/{merchantId}/inventory/categories/{categoryId}/image Deletes image of a category Deletes image on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /merchants/{merchantId}/inventory/categories/{categoryId}/products Returns products from a category Returns a list o products related to a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Responses: - 200: Successful operation - `id`: integer - `name`: string - `inventory_products`: array of object - `inventory_products[].id`: number (int64; e.g. 217) - `inventory_products[].base_price`: number (int64; e.g. 290) - `inventory_products[].name`: string (e.g. "Guinness") - `inventory_products[].unavailable_for_order_ahead`: boolean (e.g. true) - `inventory_products[].inventory_categories_products`: object - `inventory_products[].inventory_categories_products.category_id`: integer (int64) - `inventory_products[].inventory_categories_products.id`: integer (int64) - `inventory_products[].inventory_categories_products.product_id`: integer (int64) - `inventory_products[].inventory_categories_products.unavailable_for_order_ahead`: boolean (e.g. true) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /merchants/{merchantId}/inventory/categories/{categoryId}/products Update products from a category Updates products on a specific category Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | categoryId | path | integer (int64; e.g. 26867041) | yes | ID of category | Request body (application/x-www-form-urlencoded): - `ordering`: array of number Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ## Modifier Groups (by merchant ID) ### GET /merchants/{merchantId}/inventory/modifiers-groups Returns modifier groups Returns a list of modifier groups Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Responses: - 200: Successful operation - `data`: array of object - `data[].id`: number (int64; e.g. 217) - `data[].name`: string (e.g. "Add Toast & Jam") - `data[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].group_id`: number (e.g. 108) - `data[].status`: string (one of: 0, 1) - `data[].max_allowed`: number (e.g. 3) - `data[].min_required`: number (e.g. 3) - `data[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifiers`: array of object - `data[].modifiers[].id`: number (e.g. 1) - `data[].modifiers[].name`: string (e.g. "PORTIONS") - `data[].modifiers[].price`: number (e.g. 9.99) - `data[].modifiers[].image`: string (default null) - `data[].modifiers[].status`: string (one of: 0, 1) - `data[].modifiers[].description`: string (default null; e.g. "this is a description") - `data[].modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `data[].modifiers[].modifier_group_id`: number (e.g. 1) - `data[].modifiers[].order`: number (e.g. 4) - `data[].modifiers[].hidden`: boolean (e.g. false) - `data[].modifiers[].group_id`: number (e.g. 108) - `data[].modifiers[].branch_id`: number (e.g. 2534) - `data[].modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `data[].modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `total`: number (e.g. 574) - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### POST /merchants/{merchantId}/inventory/modifiers-groups creates a new modifier group Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | Request body (application/json): - `name`: string, required - `branch_id`: integer (int64; e.g. 4219), required - `order`: number - `max_allowed`: number (default null) - `min_required`: number (default null) - `modifiers`: array of object - `modifiers[].external_id`: string (default null) - `modifiers[].hidden`: boolean - `modifiers[].id`: integer (int64) - `modifiers[].name`: string - `modifiers[].oder`: number - `modifiers[].price`: number - `modifiers[].status`: integer (one of: 0, 1) Responses: - 200: Successful operation - `id`: number - `name`: string - `max_allowed`: number - `min_required`: number - `order`: number - `branch_id`: number - `status`: integer (one of: 0, 1) - `group_id`: string - `updatedAt`: string - `createdAt`: string (date) - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### GET /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId} Returns a modifier group Returns a specific modifier group Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - `branch_id`: number - `updatedAt`: string (date) - `createdAt`: string (date) - `external_id`: string - `group_id`: number - `id`: number - `image`: string - `max_allowed`: string - `min_required`: string - `name`: string - `order`: number - `status`: string - `modifiers`: array of object - `modifiers[].id`: number (e.g. 1) - `modifiers[].name`: string (e.g. "PORTIONS") - `modifiers[].price`: number (e.g. 9.99) - `modifiers[].image`: string (default null) - `modifiers[].status`: string (one of: 0, 1) - `modifiers[].description`: string (default null; e.g. "this is a description") - `modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `modifiers[].modifier_group_id`: number (e.g. 1) - `modifiers[].order`: number (e.g. 4) - `modifiers[].hidden`: boolean (e.g. false) - `modifiers[].group_id`: number (e.g. 108) - `modifiers[].branch_id`: number (e.g. 2534) - `modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId} Updates a modifier group Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `name`: string - `order`: number - `max_allowed`: number - `min_required`: number - `modifiers`: array of object - `modifiers[].id`: number (e.g. 1) - `modifiers[].name`: string (e.g. "PORTIONS") - `modifiers[].price`: number (e.g. 9.99) - `modifiers[].image`: string (default null) - `modifiers[].status`: string (one of: 0, 1) - `modifiers[].description`: string (default null; e.g. "this is a description") - `modifiers[].external_id`: string (e.g. "SDTX6S4750DZW") - `modifiers[].modifier_group_id`: number (e.g. 1) - `modifiers[].order`: number (e.g. 4) - `modifiers[].hidden`: boolean (e.g. false) - `modifiers[].group_id`: number (e.g. 108) - `modifiers[].branch_id`: number (e.g. 2534) - `modifiers[].createdAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") - `modifiers[].updatedAt`: string (date; e.g. "2022-04-04T12:31:56.000Z") Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error ### PUT /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId}/image Updates a modifier group image Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `image`: string (e.g. "https://ucarecdn.com/e7bf0263-4e0a-413d-b2b8-3e749474ed1d/-/crop/435x435/128,0/-/preview/") Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### DELETE /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId}/image Deletes a modifier group image Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### GET /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId}/products Returns a modifier group with its associated products Authentication: none. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Responses: - 200: Successful operation - `branch_id`: number - `group_id`: number - `id`: number - `name`: string - `inventory_products`: array of object - `inventory_products[].id`: number - `inventory_products[].name`: string - `inventory_products[].base_price`: number - `inventory_products[].tax_included`: integer (one of: 0, 1) - `inventory_products[].image`: string - `inventory_products[].status`: string (one of: 0, 1) - `inventory_products[].description`: string - `inventory_products[].price_type`: string - `inventory_products[].unit_name`: string - `inventory_products[].external_id`: string - `inventory_products[].external_code`: string - `inventory_products[].stock_count`: number - `inventory_products[].branch_id`: number - `inventory_products[].group_id`: number - `inventory_products[].order`: number - `inventory_products[].unavailable_for_order_ahead`: integer (one of: 0, 1) - `inventory_products[].unavailable_for_self_checkout`: integer (one of: 0, 1) - `inventory_products[].stamp_reward`: number - `inventory_products[].reward`: number - `inventory_products[].limit_stock_value`: number - `inventory_products[].limit_stock`: number - `inventory_products[].delivery`: integer (one of: 0, 1) - `inventory_products[].fixed_delivery`: integer (one of: 0, 1) - `inventory_products[].collection`: integer (one of: 0, 1) - `inventory_products[].createdAt`: string (date) - `inventory_products[].updatedAt`: string (date) - `inventory_products[].created_at`: string (date) - `inventory_products[].updated_at`: string (date) - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.id`: number - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.modifier_group_id`: number - `inventory_products[].inventory_modifiers_groups.inventory_products_modifiers_groups.product_id`: number - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found ### PUT /merchants/{merchantId}/inventory/modifiers-groups/{modifiersGroupId}/products Returns a modifier group with its associated products Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | merchantId | path | integer (int64; e.g. 253) | yes | ID of merchant | | modifiersGroupId | path | integer (int64; e.g. 253) | yes | ID of modifier group | Request body (application/x-www-form-urlencoded): - `products`: array of number Responses: - 200: Successful operation - `result`: string (e.g. "success") - 400: Invalid merchant id - 401: Invalid authentication - 404: Merchant not found # Campaigns ## Campaigns ### GET /campaigns Returns a list of campaigns Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Responses: - 200: Successful operation - `pagination`: object - `pagination.has_more_pages`: boolean - `pagination.items_per_page`: number - `pagination.page`: number - `pagination.total_items`: number - `list`: array of object - `list[].id`: number - `list[].name`: string - `list[].picture_url`: string - `list[].advertising`: boolean - `list[].coupons_quantity`: number - `list[].created_at`: string (date) - `list[].updated_at`: string (date) - `list[].description`: string - `list[].highlight`: boolean - `list[].status`: string (one of: draft, running, paused, ended) - `list[].terms_and_conditions`: string - `list[].schedules`: object - `list[].schedules.custom_daily_period`: array of string - `list[].schedules.daily_period`: array of string - `list[].schedules.days_of_week`: array of string - `list[].schedules.period_date`: object - `list[].schedules.period_date.start`: string (date) - `list[].schedules.period_date.end`: string (date) - `list[].rewards_value`: number - `list[].limits`: object - `list[].limits.budget`: number - `list[].limits.budget_email`: boolean - `list[].limits.max_coupons`: number - `list[].limits.max_coupons_email`: boolean - `list[].limits.max_coupons_per_user`: number - `list[].limits.max_coupons_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) - `list[].limits.max_value_per_user`: number - `list[].limits.max_value_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### GET /campaigns/{campaignId} Returns a campaign Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Responses: - 200: Successful operation - `id`: number - `name`: string - `picture_url`: string - `advertising`: boolean - `coupons_quantity`: number - `created_at`: string (date) - `updated_at`: string (date) - `description`: string - `highlight`: boolean - `status`: string (one of: draft, running, paused, ended) - `terms_and_conditions`: string - `schedules`: object - `schedules.custom_daily_period`: array of string - `schedules.daily_period`: array of string - `schedules.days_of_week`: array of string - `schedules.period_date`: object - `schedules.period_date.start`: string (date) - `schedules.period_date.end`: string (date) - `rewards`: object - `rewards.discount_product`: object - `rewards.discount_product.item_limit`: number - `rewards.discount_product.value`: number - `rewards.discount_product.value_type`: string (one of: money, percent) - `rewards.discount_product.selector`: object - `rewards.discount_product.selector.date`: string (date) - `rewards.discount_product.selector.productsSelection`: array of object - `rewards.discount_product.selector.categoriesSelection`: array of object - `rules`: object - `rules.products`: object - `rules.products.values`: array of object - `rules.products.values[].amount`: string (e.g. "6") - `rules.products.values[].period_type`: string (one of: day, week, month, year) - `rules.products.values[].period_value`: number - `rules.products.values[].selector`: object - `rules.gender`: object - `rules.gender.values`: array of string - `rules.age`: object - `rules.age.values`: array of object - `rules.age.values[].start`: string (e.g. "10") - `rules.age.values[].end`: string (e.g. "13") - `rules.customer_domains`: object - `rules.customer_domains.values`: array of string - `rules.birthday`: object - `rules.birthday.value`: string (one of: month_of_birthday, week_of_birthday, days_around, day_of_birthday) - `rules.lapsed_customers`: object - `rules.lapsed_customers.value`: object - `rules.lapsed_customers.value.period`: string (one of: day, week, month) - `rules.lapsed_customers.value.value`: number - `rules.cake_day`: object - `rules.cake_day.value`: object - `rules.cake_day.value.period`: string (one of: day, week, month) - `rules.cake_day.value.value`: number - `rules.visits`: object - `rules.visits.values`: array of object - `rules.visits.values[].period_type`: string (one of: day, week, year) - `rules.visits.values[].period_value`: number - `rules.visits.values[].recurring_type`: string (e.g. "day") - `rules.visits.values[].recurring_value`: number - `rules.visits.values[].value`: string (e.g. "2") - `rules.visits.values[].value_type`: string (e.g. "total") - `rules.transaction_types`: object - `rules.transaction_types.values`: object - `rules.transaction_types.values.amount`: number - `rules.transaction_types.values.period_type`: string (one of: day, week, month) - `rules.transaction_types.values.period_value`: number - `rules.transaction_types.values.types`: array of string - `rules.spent`: object - `rules.spent.values`: array of object - `rules.spent.values[].period_type`: string (one of: day, week, month, year) - `rules.spent.values[].period_value`: number - `rules.spent.values[].recurring_type`: string (e.g. "day") - `rules.spent.values[].recurring_value`: number - `rules.spent.values[].value`: string (e.g. "1300") - `rules.top_visitors`: object - `rules.top_visitors.values`: array of object - `rules.top_visitors.values[].period_value`: number - `rules.top_visitors.values[].period_type`: string (one of: day, week, month, year) - `rules.top_visitors.values[].amount`: number - `rules.top_spenders`: object - `rules.top_spenders.values`: array of object - `rules.top_spenders.values[].period_value`: number - `rules.top_spenders.values[].period_type`: string (one of: day, week, month, year) - `rules.top_spenders.values[].amount`: number - `rules.role`: object - `rules.role.ids`: array of string - `rules.branches`: object - `rules.branches.ids`: array of string - `rules.customers`: object - `rules.customers.ids`: array of string - `rewards_value`: number - `notification`: object - `notification.id`: number - `notification.campaign_id`: number - `notification.picture_url`: string - `notification.enabled`: boolean - `notification.general_message`: string - `notification.general_message_date`: string (date; e.g. "2023-06-22T09:15:29.790Z") - `notification.general_message_enabled`: boolean - `notification.general_title`: string - `notification.applicable_customers_message`: string - `notification.applicable_customers_message_enabled`: boolean - `notification.applicable_customers_title`: string - `notification.applicable_customers_notification_event`: string (one of: once_applicable, 10_min_after, 8am_following_day) - `limits`: object - `limits.budget`: number - `limits.budget_email`: boolean - `limits.max_coupons`: number - `limits.max_coupons_email`: boolean - `limits.max_coupons_per_user`: number - `limits.max_coupons_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) - `limits.max_value_per_user`: number - `limits.max_value_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/notifications Updates a campaign notification Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `enabled`: boolean - `general_message`: string - `general_message_date`: string (date; e.g. "2023-06-22T09:15:29.790Z") - `general_message_enabled`: boolean - `general_title`: string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/highlight Updates a campaign highlight Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/status Updates a campaign status Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `status`: string (one of: draft, running, paused, ended) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/basic Updates a campaign Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `advertising`: boolean - `description`: string - `name`: string - `picture_url`: string - `terms_and_conditions`: string - `schedules`: object - `schedules.custom_daily_period`: array of string - `schedules.daily_period`: array of string - `schedules.days_of_week`: array of string - `schedules.period_date`: object - `schedules.period_date.start`: string (date) - `schedules.period_date.end`: string (date) - `limits`: object - `limits.budget`: number - `limits.budget_email`: boolean - `limits.max_coupons`: number - `limits.max_coupons_email`: boolean - `limits.max_coupons_per_user`: number - `limits.max_coupons_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) - `limits.max_value_per_user`: number - `limits.max_value_per_user_period`: string (one of: daily, weekly, fortnightly, monthly, yearly, all) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### GET /campaigns/{campaignId}/transactions Returns a campaign transactions Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | | exports_to | query | string (one of: csv) | no | Export format. When set to 'csv', returns a URL to the exported file instead of paginated data. | | transform | query | string (one of: campaign_weekly_report, campaign_monthly_report) | no | Transformation script to apply to the exported CSV. Produces an XLSX report. Only used when exports_to=csv. | Responses: - 200: Successful operation - body variant 1: - `total`: number (e.g. 54) - `data`: array of object - `data[].user_name`: string - `data[].user_id`: number - `data[].total`: number - `data[].reward_type`: string (one of: discount, discount_product, cashback, topup) - `data[].created_at`: string (date) - body variant 2: - `data`: string (e.g. "https://s3-eu-west-1.amazonaws.com/bucket/02/11/campaign_transactions_abc123.csv"). URL to the exported CSV or transformed XLSX file - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### GET /campaigns/{campaignId}/stats Returns a campaign stats Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Responses: - 200: Successful operation - `has_some_transaction`: boolean - `charts`: object - `charts.coupons_and_rewards_stats`: object - `charts.coupons_and_rewards_stats.type`: string (one of: hours, days, months) - `charts.coupons_and_rewards_stats.data`: array of object - `charts.coupons_and_rewards_stats.data[].data`: object - `charts.coupons_and_rewards_stats.data[].interval_dates`: array of string - `general`: object - `general.impacted_customers`: number - `general.remaining_budget_percentage`: number - `general.remaining_coupons_percentage`: number - `general.spent_budget`: number - `general.spent_coupons`: number - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ## Segmentation Rules ### PUT /campaigns/{campaignId}/rules/gender Updates a campaign gender rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: string (one of: male, female, unknown) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/age Updates a campaign age rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: array of object - `values[].start`: number - `values[].end`: number Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/customer_domains Updates a campaign customer domains rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/birthday Updates a campaign birthday rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `value`: string (one of: week_of_birthday, month_of_birthday, days_around, day_of_birthday) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/lapsed_customers Updates a campaign lapsed customers rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `value`: number - `period`: string (one of: day, week, month) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/cake_day Updates a campaign cake day rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `value`: object - `value.period`: string (one of: day, week, month) - `value.value`: number Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/visits Updates a campaign visits rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: object - `values.period_type`: string (one of: day, week, month, year) - `values.period_value`: number - `values.recurring_type`: string - `values.recurring_value`: number - `values.value`: number - `values.value_type`: string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/spent Updates a campaign spent rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: object - `values.value`: number - `values.recurring_value`: number - `values.recurring_type`: string - `values.period_value`: number - `values.period_type`: string (one of: day, week, month, year) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/products Updates a campaign products rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: object - `values.amount`: string (e.g. "6") - `values.period_type`: string (one of: day, week, month, year) - `values.period_value`: number - `values.selector`: object - `values.selector.productsSelection`: array of object - `values.selector.productsSelection[].productId`: string (e.g. "701609") - `values.selector.productsSelection[].modifiersIdsExclusionList`: array of string - `values.selector.categoriesSelection`: array of object - `values.selector.categoriesSelection[].categoryId`: string (e.g. "701609") - `values.selector.categoriesSelection[].productsIdsExclusionList`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/top_visitors Updates a campaign top visitors rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: object - `values.period_value`: number - `values.period_type`: string (one of: day, week, month, year) - `values.amount`: number Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/top_spenders Updates a campaign top spenders rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `values`: object - `values.period_value`: number - `values.period_type`: string (one of: day, week, month, year) - `values.amount`: number Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/role Updates a campaign role rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `ids`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/branches Updates a campaign branches rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `ids`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/customers Updates a campaign customers rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `ids`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rules/transaction_types Updates a campaign transaction types rule Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `amount`: number - `period_type`: string (one of: day, week, month) - `period_value`: string (e.g. "1") - `types`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ## Rewards ### PUT /campaigns/{campaignId}/rewards/discount Updates a campaign discount reward Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `sales_value`: number - `value`: number - `value_type`: string (one of: percent, money) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rewards/discount_product Updates a campaign discount_product reward Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `item_limit`: string (e.g. "2") - `value`: number - `value_type`: string (one of: percent, money) - `selector`: object - `selector.productsSelection`: array of object - `selector.productsSelection[].productId`: string (e.g. "701609") - `selector.productsSelection[].modifiersIdsExclusionList`: array of string - `selector.categoriesSelection`: array of object - `selector.categoriesSelection[].categoryId`: string (e.g. "701609") - `selector.categoriesSelection[].productsIdsExclusionList`: array of string Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rewards/cashback Updates a campaign cashback reward Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `sales_value`: number - `value`: number - `value_type`: string (one of: percent, money) Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found ### PUT /campaigns/{campaignId}/rewards/voucher Updates a campaign voucher reward Authentication (any one): authorization (header `authorization`). Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | campaignId | path | integer (int64; e.g. 253) | yes | ID of campaign | Request body (application/x-www-form-urlencoded): - `amount`: number Responses: - 200: Successful operation - `message`: string (e.g. "OK") - 400: Invalid campaign id - 401: Invalid authentication - 404: Campaign not found # Payments ## Payments ### POST /payments Redeem or load stored value on a customer's card Debits or credits a customer's stored-value balance. A gift card redemption is `payment_type=gift` with a **negative** `amount`; a positive amount loads value. See "Redeem gift cards at a point of sale" in the introduction for the full flow. The merchant is resolved from the user who created the API key (their first owned merchant), not from `merchant_id`. Deprecated: this endpoint will be replaced by an order-based endpoint; requests that pass validation get `Deprecation` and `Sunset` headers. It is not idempotent, and it returns `401` for an insufficient balance as well as for authentication failures. Authentication (any one): authorization (header `authorization`), ApiKeyAuth (header `X-API-Key`). Request body (application/x-www-form-urlencoded): - `payment_type`: string (one of: cash, stamp, upfront, gift, cashless), required. `gift` redeems (negative amount) or loads (positive amount) stored value at face value. `upfront` and `cashless` load stored value and add the merchant's top-up bonus. `cash` records a sale paid by other means and awards cashback. `stamp` adds or removes loyalty stamps. - `merchant_id`: string. Optional external merchant id from your POS or terminal provider, used only to attribute the transaction to the matching branch. It does not choose the merchant that is debited. Leave it out unless Facilipay support has given you a value; without it the employee's branch is used. - `customer_id`: string (e.g. "12345678"), required. The card number (account number) printed on the card or encoded in the wallet pass QR code. Not the customer's numeric id. - `amount`: integer (int64; e.g. -2550), required. Amount in minor units (cents): €25.50 is 2550. Negative to redeem, positive to load. For `stamp`, the number of stamps. - `identifier`: string (e.g. "POS-1042-000731"). Your reference for this transaction, unique per sale (e.g. a receipt number). Look a payment up by it with `GET /merchants/{merchantId}/transactions/byUniqueId/{uniqueIdentifier}`. - `employee_email`: string. Email of the merchant employee taking the payment, recorded on the transaction. Defaults to the API key's user. - `product_data`: string - `skip_cashback`: boolean - `cashback_rewards`: string - `terminal_id`: string. Your till or terminal id, stored on the transaction. Responses: - 200: Transaction processed. The response does not include the new balance. - `error`: boolean (e.g. false) - `message`: string (e.g. "Transaction Processed") - `group_id`: integer (int64; e.g. 201). Facilipay id of the merchant that was debited or credited. - 400: Validation failed, unknown card (`Account doesnt exist`), expired card, or the API key's user is not an employee of the merchant (`Invalid parameters`). - 401: Invalid or expired credentials, OR the balance is too low (`INSUFFICIENT BALANCE`; nothing was debited), OR the card is blocked or expired. Read `message` before treating it as an authentication failure. - 403: The API key lacks the `payments:write` scope, or the customer is blocked at this merchant. - 422: The API key's user is not linked to a merchant. - 500: Unexpected error, including a lost connection to the payment service mid-request. The debit may or may not have happened; wait a minute and check with `GET /merchants/{merchantId}/transactions/byUniqueId/{identifier}` before retrying. - 502: The payment service could not be reached or failed upstream. The debit may or may not have happened; wait a minute and check with `GET /merchants/{merchantId}/transactions/byUniqueId/{identifier}` before retrying. ## Gift Cards ### POST /gift-card/digital/send Send digital giftcard Sends an electronic gift card to a user email from the merchant Authentication (any one): authorization (header `authorization`). Request body (application/json): - `loyalty_type`: string (e.g. "gift"), required - `merchant_id`: integer (int64). Merchant the voucher is sent for. Must be a merchant the token holds a merchant or employee permission for (403 otherwise). Defaults to the token's merchant. - `card_number`: string - `identifier`: string (e.g. "645e464ba7cc1 | Insertion time: 16838999796 | Customer ID: 554046543 | Amount: 200") - `product_data`: string - `message`: string - `sender_name`: string (e.g. "Nobody"), required - `recipient_name`: string (e.g. "Nobody"), required - `employee_email`: string (e.g. "Nobody@facilipay.io"), required - `recipient_email`: string (e.g. "Nobody@facilipay.io"), required - `sender_email`: string (e.g. "Nobody@facilipay.io") Responses: - 200: Successful operation - `error`: boolean (e.g. false) - `message`: string (e.g. "Email sent successfully") - 400: Bad request - 401: Invalid authentication - 500: Internal Server Error