# Get a card Source: https://developers.perkstar.co.uk/api-reference/cards/get-a-card /api/openapi.yaml get /cards/{id} # List cards Source: https://developers.perkstar.co.uk/api-reference/cards/list-cards /api/openapi.yaml get /cards # Anonymize (GDPR Article 17 erasure) a customer Source: https://developers.perkstar.co.uk/api-reference/customers/anonymize-gdpr-article-17-erasure-a-customer /api/openapi.yaml delete /customers/{id} # Create or upsert a customer Source: https://developers.perkstar.co.uk/api-reference/customers/create-or-upsert-a-customer /api/openapi.yaml post /customers When `external_ref` is supplied, the endpoint upserts on the unique `(orgId, externalRef)` key: • Existing match → returns the existing record with HTTP 200. No fields are overwritten. • No match → creates a new customer, HTTP 201. Without `external_ref`, the endpoint always creates and returns HTTP 201 (or 409 if the supplied email already exists in the org). `Idempotency-Key` remains the 24h replay cache; the externalRef upsert is the permanent semantic dedupe. # Get a customer Source: https://developers.perkstar.co.uk/api-reference/customers/get-a-customer /api/openapi.yaml get /customers/{id} # List customers Source: https://developers.perkstar.co.uk/api-reference/customers/list-customers /api/openapi.yaml get /customers # Update a customer Source: https://developers.perkstar.co.uk/api-reference/customers/update-a-customer /api/openapi.yaml patch /customers/{id} # Create an enrollment Source: https://developers.perkstar.co.uk/api-reference/enrollments/create-an-enrollment /api/openapi.yaml post /enrollments # Get an enrollment Source: https://developers.perkstar.co.uk/api-reference/enrollments/get-an-enrollment /api/openapi.yaml get /enrollments/{id} # List enrollments Source: https://developers.perkstar.co.uk/api-reference/enrollments/list-enrollments /api/openapi.yaml get /enrollments # Update an enrollment Source: https://developers.perkstar.co.uk/api-reference/enrollments/update-an-enrollment /api/openapi.yaml patch /enrollments/{id} # List locations Source: https://developers.perkstar.co.uk/api-reference/locations/list-locations /api/openapi.yaml get /locations # Auth check + org context Source: https://developers.perkstar.co.uk/api-reference/marketplace/auth-check-+-org-context /api/openapi.yaml get /marketplace/ping Confirms the API key is valid + returns the operator's org context (name, currency, timezone) and the available cards. First call every POS adapter makes on install. Requires NO specific scope — any valid (non-revoked, non-expired) key works. Brute-force / rate-limit protection still applies. # Find-or-create customer + enrolment (no transaction) Source: https://developers.perkstar.co.uk/api-reference/marketplace/find-or-create-customer-+-enrolment-no-transaction /api/openapi.yaml post /marketplace/enroll Same identifier resolution + create-on-miss as `/marketplace/accrue`, but without posting a transaction. Used by checkout-time signup flows (Shopify customers/create, Toast guest-create) where the partner wants the customer on the loyalty programme but doesn't have a purchase to credit yet. Idempotent on `(customer, card)` — repeating the call returns the same enrolment at HTTP 200. This endpoint changes live customer data and therefore rejects test credentials with 403. # Find-or-create customer + post transaction in one call Source: https://developers.perkstar.co.uk/api-reference/marketplace/find-or-create-customer-+-post-transaction-in-one-call /api/openapi.yaml post /marketplace/accrue Resolves the customer in this fixed priority order: 1. customer_id → tenant-scoped Perkstar customer 2. card_serial → POS barcode or legacy pass serial → customer 3. external_ref → (orgId, externalRef) lookup 4. email (case-insensitive) 5. phone (normalised E.164 with a legacy raw-value fallback) First match wins. On miss, creates a customer when `create_customer_if_missing` is true (the default). A missing `customer_id` alone returns 404 instead of creating a replacement. The `transaction.external_transaction_id` field is enforced as permanently unique per `(orgId, externalTransactionId)`. An exact retry with the same canonical target, type, amount, and request fields returns the existing transaction at HTTP 200 instead of double-crediting, no matter how long has passed. Reusing the id for a different request returns `409 external_transaction_id_conflict`. Use this for POS-side stable ids (Toast order #s, Shopify checkout ids, Square payment ids). Test and live transactions cannot share the same value; a cross-environment replay is rejected with 422. Provider-owned prefixes such as `sq_payment_` are reserved for managed integrations; use a namespace owned by your app. `Idempotency-Key` (24h replay cache) and `external_transaction_id` (permanent dedupe) coexist — use both for full robustness. With a test credential this endpoint never creates a customer or enrolment. Resolve an existing record and card first, then post the isolated transaction. A missing customer or enrolment returns 404. # Reverse a previously-posted transaction Source: https://developers.perkstar.co.uk/api-reference/marketplace/reverse-a-previously-posted-transaction /api/openapi.yaml post /marketplace/reverse Creates a compensating Transaction row whose `delta` is the negation of the original's, linked via `reverses_transaction_id`. Fires `TRANSACTION_CREATED` so partner webhooks notice the reversal end-to-end. Idempotent: reversing the same transaction twice returns the existing reversal at HTTP 200 (enforced by the unique constraint on `Transaction.reversesTransactionId` + a P2002 fallback). Cannot reverse: • An already-reversed transaction's reversal (post a new accrue instead). • A transaction in the opposite mode — live keys can't reverse test rows and vice versa. Pass either `transaction_id` (Perkstar's id) OR `external_transaction_id` (your POS-side id). Both forms resolve to the same underlying row. # Receive a perkstar outbound event Source: https://developers.perkstar.co.uk/api-reference/outbound-webhooks/receive-a-perkstar-outbound-event /api/openapi.yaml webhook perkstarEvent Perkstar POSTs this signed envelope to each active endpoint subscribed to the event. Client-managed integrations verify `X-Perkstar-Signature` against the exact raw body. Approved OAuth connectors can instead use Perkstar's server-attested verification contract without receiving the signing secret. Persist and deduplicate by `id`, then return a `2xx` response. Automatic retries keep the same logical delivery `id`. # Send a wallet push Source: https://developers.perkstar.co.uk/api-reference/pushes/send-a-wallet-push /api/openapi.yaml post /pushes Sends a marketing wallet push to a specific enrolment. The customer must have push-marketing consent enabled, otherwise the endpoint returns 403 with `push_marketing_consent_required`. Merge fields (`{firstName}`, `{balance}`, `{installLink}`, `{shareLink}`, `{cardName}`, `{orgName}`) are resolved against the targeted customer + enrolment + card. Throttle: 3-minute per-card cooldown. Hit → 429 with `Retry-After`. The cooldown is shared with the operator's dashboard push paths so a rapid dashboard + API sequence is also caught. Test mode (`pk_test_…` or OAuth `mode=TEST`): the endpoint returns 200 with `test_mode: true` but does NOT push. Lets partners verify wire integration without spamming real customer lock screens. Requests without `Idempotency-Key` return 400 with the stable error code `idempotency_key_required` and no Wallet mutation. # Bulk-delete every test-mode transaction for the org Source: https://developers.perkstar.co.uk/api-reference/transactions/bulk-delete-every-test-mode-transaction-for-the-org /api/openapi.yaml delete /transactions/test Sandbox cleanup. Requires a `pk_test_…` key — live keys are rejected with 403. Returns the row count deleted. Aggregates on Customer / Card / Enrollment do not need recomputing because test rows never contributed to them. # List transactions Source: https://developers.perkstar.co.uk/api-reference/transactions/list-transactions /api/openapi.yaml get /transactions # Post a transaction (stamp / redeem / adjust) Source: https://developers.perkstar.co.uk/api-reference/transactions/post-a-transaction-stamp-redeem-adjust /api/openapi.yaml post /transactions # Create a webhook Source: https://developers.perkstar.co.uk/api-reference/webhooks/create-a-webhook /api/openapi.yaml post /webhooks Direct API-key requests use the normal 24-hour idempotency response cache. For OAuth REST-hook clients, the idempotency key remains bound to the live subscription until DELETE. A retry with the same event set returns that row; use PATCH to apply a current URL, card, mode, or active state. `client_hmac` subscriptions return their signing secret on create and OAuth idempotent replay. OAuth-only `server_attested` subscriptions keep the signing secret inside Perkstar and omit it from every response. Reusing the key for a different event set or verification mode returns an idempotency conflict. # Delete a webhook Source: https://developers.perkstar.co.uk/api-reference/webhooks/delete-a-webhook /api/openapi.yaml delete /webhooks/{id} # Get a webhook Source: https://developers.perkstar.co.uk/api-reference/webhooks/get-a-webhook /api/openapi.yaml get /webhooks/{id} # List recent outbound events Source: https://developers.perkstar.co.uk/api-reference/webhooks/list-recent-outbound-events /api/openapi.yaml get /events Returns one canonical row per source event, newest first. REST-hook integrations use this endpoint to load representative sample data whose keys and types match the live webhook envelope. Live events are returned by default; request `mode=test` or `mode=all` explicitly when validating sandbox activity. Event rows are retained for 90 days and require the dedicated `EVENTS_READ` scope. # List webhooks Source: https://developers.perkstar.co.uk/api-reference/webhooks/list-webhooks /api/openapi.yaml get /webhooks # Update a webhook Source: https://developers.perkstar.co.uk/api-reference/webhooks/update-a-webhook /api/openapi.yaml patch /webhooks/{id} # Verify a server-attested webhook delivery Source: https://developers.perkstar.co.uk/api-reference/webhooks/verify-a-server-attested-webhook-delivery /api/openapi.yaml post /webhooks/deliveries/verify OAuth-only callback proof endpoint for approved automation connectors. It binds the parsed event and retention-bounded Perkstar delivery headers to the exact outbound attempt committed before dispatch. Authenticated proof failures deliberately return the same `{ "verified": false }` response so webhook IDs, delivery IDs, and proof state cannot be enumerated. Ordinary client-managed HMAC integrations do not use this endpoint. # Changelog Source: https://developers.perkstar.co.uk/changelog Developer-facing changes to the Perkstar API, SDK, and integration guidance. ## 13 September 2026 — Resend and integration setup guides * Connect your own Resend account inside the integration workspace for supported invitations and card-install emails. * Follow the signed delivery test before choosing when to activate; a failed own-account connection never falls back to Perkstar's shared sender. * Find every provider in the integration directory, with setup guides for available connections and explicit availability notes for limited or unreleased providers. * Browse guides by task, with detailed provider sections grouped in the sidebar. See [Resend setup](/integrations/resend/setup) and the [integration directory](/integrations). ## August 2026 ### Loyverse existing-customer migration * Added a guided transfer that reads the current Loyverse customer directory, copies each current points balance to the exact Perkstar membership and continues safely in the background without requiring a merchant CSV. * Added a default-off, owner-only choice to give eligible existing customers the selected card's normal welcome points. Perkstar shows the maximum points, cash-equivalent exposure and expiry before confirmation, then keeps the choice fixed across retries and reconnects. * Added business-controlled migration invitations: an included service email, paid SMS after subscription activation and credit purchase, or both. Known Loyverse contact details stay locked to the migrated membership so customers cannot accidentally claim an empty duplicate account. * Added readiness gates, retry-safe results and explicit migration timing for larger customer lists. Invitations, scanning and till redemption remain unavailable until the relevant preceding checks are complete. * Added Teya camera and SUNMI Blink guidance, including the requirement to test USB HID/keyboard and host/OTG support on the exact terminal or dock. * Made the saved Loyverse card unmistakable, including conservative confirmation when a paid poster order can be tied to the unchanged card design, and removed the extra card-creation prompt once a compatible card is saved. * Added explicit prerequisite lists beside unavailable setup actions, a direct Step 2 guide link and actionable missing-permission connection errors. * Added redacted, support-visible Step 2 attempt references plus a one-click setup diagnostic snapshot that excludes customer details, individual balances, tokens and raw provider errors. * Added a one-recipient migration rehearsal over included email or paid SMS, with exact recipient, message and credit confirmation before the business releases either remaining audience. ### Zapier public Beta * Perkstar version 1.0.0 is now available in [Zapier's public App Directory](https://zapier.com/apps/perkstar/integrations); a Zapier invitation is no longer required. * Added a direct public connection path, clarified that one OAuth connection represents one Perkstar business and can be reused across multiple Zaps, and documented separate connections for additional businesses. * Split support ownership between Perkstar connection/API issues, Zapier account/editor issues, and failures in other connected apps. * Added a self-serve Zapier page in the Perkstar integration settings with public directory, setup-guide, and safe app-pairing links. * Submitted five launch templates to Zapier review. A sixth Square template is held in Draft until a customer-attributed sample verifies its buyer-email mapping; customer-facing template links will be added only after approval. * Replaced invite-only setup and troubleshooting guidance throughout the developer portal. The earlier pre-release notes below describe the state before publication. ### Make private-beta package * Added a source-controlled Make custom app with tenant-scoped OAuth 2.0, PKCE, rotating refresh tokens, and an attached instant webhook. * Added one **Watch a Loyalty Event** module covering all 29 public business events, 11 guided actions, two paginated searches, five filtered Card selectors, and the required fixed-origin **Make an API Call** module. * Added seven self-serve guides covering setup, the full module catalogue, recipes, webhook delivery, troubleshooting, privacy, and security. * Documented the eight default OAuth permissions, five optional advanced permissions, retry-safe writes, rate-limit handling, and server-attested webhook verification that keeps signing secrets inside Perkstar. * The app remains private while live scenarios and Make review evidence are completed; it is not yet available in Make's public catalogue. ### Zapier pre-release package (historical) * Added source-ready documentation for Perkstar's first-party Zapier app. * Documented OAuth connection, Growth-and-above eligibility, and the private-invitation boundary before public App Directory review. Private version 1.0.0 is registered and available to invited Zapier accounts, but is not yet listed publicly. * Expanded the complete named instant-trigger catalogue to 29 business events; the diagnostic `webhook.test` event remains excluded. * Added `wallet.installed`, `card.scanned`, `card.expired`, `customer.group_changed`, and `referral.created`, with explicit provider, online-scanner, per-enrolment expiry, lifecycle-group, and customer-referral boundaries. * Documented all 10 visible actions, two searches, both explicit Search-or-Create relationships, the dynamic card selector, webhook retry identity, recipes, troubleshooting, and data-handling model. * Added direct Customer ID lookup to **Find Customer** so trigger records can be enriched without matching personal identifiers again. * Bound each permanent loyalty Source ID to its first canonical request; an exact retry replays safely, while changed customer/card/operation inputs now return `409 external_transaction_id_conflict`. * Documented the one-sweep warm-up boundary for a business's first lifecycle group or Google-install trigger; Apple installation remains callback-driven. * Added the dedicated `EVENTS_READ` permission for the bounded 90-day sample feed, without broadening existing `WEBHOOKS_READ` credentials. * Documented signed callback verification and the app-managed subscription lifecycle; Zapier-owned hooks cannot be edited, rotated, or deleted from the custom-webhook dashboard. ## July 2026 ### Developer portal * Added a dedicated guide and generated API reference for integration teams. * Added production recipes for POS, Odoo, customer sync, webhooks, and wallet pushes. * Added a security and operational go-live checklist. * Added the official Python SDK with retries, pagination, typed errors, and webhook verification. * Added a generated Postman collection and production environment covering all public v1 operations. * Added a public component status page and machine-readable status endpoint. ### API key safety * Direct API-key presets no longer include the internal OAuth-only MCP scope. * MCP access now explicitly requires an OAuth token. * Test keys cannot mutate customers, enrolments, or webhook configuration. * Test marketplace accrual is restricted to existing customers and enrolments. * Direct browser playground calls accept only approved Perkstar developer-portal origins. ### Documentation contract * Test-mode limitations are now part of the canonical OpenAPI description. * Documentation navigation and links are validated in CI. * SDK packages, Postman assets, and OpenAPI operation coverage are validated before release. ## May 2026 * Added the v1 REST API, scoped API keys, OAuth access tokens, cursor pagination, and request tracing. * Added POS-friendly marketplace ping, accrue, enrol, and reverse endpoints. * Published the official zero-dependency TypeScript SDK. # Authentication and scopes Source: https://developers.perkstar.co.uk/fundamentals/authentication Protect API credentials and grant only the permissions an integration needs. Perkstar accepts a bearer credential in the `Authorization` header: ```http theme={null} Authorization: Bearer pk_live_... ``` Direct integrations use an API key. Marketplace applications use OAuth access tokens beginning with `perk_at_`. Both credential types use the same endpoint shapes and error format. The public [Perkstar app for Zapier](/integrations/zapier) uses Perkstar OAuth. Users approve the hosted consent screen and never copy a raw Perkstar API key into a Zap field. ## API key environments | Prefix | Intended use | Live-data writes | | - | - | - | | `pk_test_` | Development and certification | Only isolated test transactions and simulated pushes | | `pk_live_` | Production traffic | Allowed when the key has the required scope | The environment is part of the signed secret. Renaming or rotating a key does not change its environment. ## Available direct-key scopes | Scope | Allows | | - | - | | `CUSTOMERS_READ` | Find and list customers | | `CUSTOMERS_WRITE` | Create, update, or anonymise customers | | `ENROLLMENTS_READ` | Read loyalty enrolments and balances | | `ENROLLMENTS_WRITE` | Create or update enrolments | | `TRANSACTIONS_READ` | Read live or test ledger rows | | `TRANSACTIONS_WRITE` | Post stamps, redeems, and adjustments | | `CARDS_READ` | Read card configuration | | `EVENTS_READ` | Read the recent loyalty-event feed | | `WEBHOOKS_READ` | Inspect webhook endpoints | | `WEBHOOKS_WRITE` | Create, edit, or remove webhook endpoints | | `LOCATIONS_READ` | Map Perkstar locations to external systems | | `PUSHES_WRITE` | Send or simulate a wallet push | | `MARKETPLACE` | Use the POS-friendly marketplace endpoints | Test keys cannot be granted `CUSTOMERS_WRITE`, `ENROLLMENTS_WRITE`, or `WEBHOOKS_WRITE`. The `MCP` permission is internal to OAuth consent and is never available to direct API keys. ## Least-privilege examples * **Read-only reporting:** customers read, enrolments read, transactions read, cards read. * **POS till:** marketplace and locations read. * **CRM sync:** customers read/write and enrolments read/write. * **Wallet messaging:** customers read, enrolments read, pushes write. * **Webhook consumer setup:** webhooks read/write; add events read only when it needs the recent-event feed. ## Credential handling 1. Keep keys in an encrypted server-side secret store. 2. Use separate keys for each integration and environment. 3. Give each key a name that identifies its owner and purpose. 4. Set an expiry where the integration can rotate automatically. 5. Rotate immediately after accidental exposure or team-member departure. 6. Revoke unused keys rather than leaving them dormant. Never send an API key to a browser or expose it in a public Odoo client action. Calls must originate from trusted server code. The hosted API request builder is for short-lived testing with a test key on a trusted device. Do not enter a live key on a shared computer, and never copy its browser-based request pattern into a customer-facing application. # Errors and request tracing Source: https://developers.perkstar.co.uk/fundamentals/errors Handle Perkstar API failures consistently and give support enough detail to trace them. API errors use one predictable envelope: ```json theme={null} { "error": { "type": "validation_error", "code": "invalid_request_body", "message": "The request body is invalid.", "param": "transaction.type" } } ``` ## Status codes | Status | Meaning | | - | - | | `400` | Malformed JSON or invalid request shape | | `401` | Missing, invalid, expired, or revoked credential | | `403` | The key lacks a scope, plan access, or live-write permission | | `404` | The requested record does not exist in this business | | `409` | The request conflicts with existing data or idempotency state | | `410` | The key or business has been permanently closed or revoked | | `422` | The request is valid JSON but incompatible with the card or balance | | `429` | The key exceeded its rate limit | | `5xx` | Perkstar could not complete an otherwise valid request | ## Universal response headers Every success and error includes: * `X-Request-Id`: the exact request reference for logs and support. * `X-API-Version`: the date-versioned contract served by the endpoint. * `X-RateLimit-Limit`: the credential's current per-minute allowance. * `X-RateLimit-Remaining`: calls left in the current window. * `X-RateLimit-Reset`: Unix seconds when the window resets. * `Retry-After`: seconds to wait after a `429`. Log the request ID, endpoint, status, error code, and your own operation ID. Do not log bearer credentials, full customer payloads, or webhook secrets. ## Unknown outcomes If the connection drops after a POST, treat the result as unknown rather than failed. Retry with the same `Idempotency-Key`. For POS transactions, send the same `external_transaction_id` as well. `400 reserved_external_transaction_id` means the identifier used a namespace owned by a managed POS integration. Choose a stable prefix belonging to your app and retry with a new identifier. ## Contacting support Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with: 1. `X-Request-Id`; 2. UTC timestamp; 3. HTTP method and path; 4. response status and error code; and 5. the first 12-character key prefix shown in the dashboard. Never include the full API key or personal customer data. # Idempotency and retries Source: https://developers.perkstar.co.uk/fundamentals/idempotency Retry requests without adding the same stamp, point award, or enrolment twice. Networks fail in awkward places. A timeout does not tell you whether Perkstar accepted a request, so every production integration must be safe to retry. ## Request idempotency Send an `Idempotency-Key` with every POST request: ```http theme={null} Idempotency-Key: order-94721-loyalty-v1 ``` Use a stable value for one logical operation, not a new random value on each retry. Perkstar keeps the result for 24 hours and returns the same outcome when the same request is repeated. OAuth REST-hook creation has a resource-lifecycle exception. For `POST /webhooks`, the idempotency key remains bound to the live subscription until that row is deleted, and a retry returns its signing secret. The event set must stay the same; apply a current callback URL, card, live/test mode, or active state with `PATCH /webhooks/:id`. Deleting the subscription releases the key immediately. Reusing one key for a different request body is an integration error. Create a new key only when you intend to perform a new operation. ## Permanent transaction deduplication POS and commerce integrations should also send `transaction.external_transaction_id` to `/marketplace/accrue`. ```json theme={null} { "transaction": { "type": "STAMP", "external_transaction_id": "odoo-pos-order-94721" } } ``` This reference is unique for the business and remains a deduplication key after the 24-hour request cache expires. A repeated call returns the existing transaction with `idempotent_replay: true`. Use an upstream ID that is: * stable across webhook retries; * unique to one loyalty operation; * available again when a refund must reverse the operation; and * namespaced when several stores can produce the same numeric order ID. Good: `odoo:shop_12:pos_order:94721` Risky: `94721` Keep test and live references in separate namespaces, for example `test:odoo:shop_12:pos_order:94721` and `live:odoo:shop_12:pos_order:94721`. Perkstar rejects a permanent transaction reference that already belongs to the other environment instead of silently replaying it. ## Retry policy | Result | Action | | - | - | | Network error or timeout | Retry with the same idempotency key | | `429` | Wait for `Retry-After`, then retry | | `500`, `502`, `503`, `504` | Retry with exponential backoff and jitter | | `400`, `403`, `404`, `409`, `422` | Fix the request or state; do not blindly retry | | `401` | Replace or rotate the credential before retrying | A practical schedule is 1 second, 2 seconds, 4 seconds, then a background retry queue. Cap attempts and surface terminal failures for an operator to inspect. ## Reversals Reverse a transaction by Perkstar ID or by its original `external_transaction_id`. Give the reversal its own idempotency key. Test and live transactions cannot be reversed across environments. Use an identifier namespace owned by your integration; provider-managed prefixes such as `sq_payment_` are reserved. # Pagination Source: https://developers.perkstar.co.uk/fundamentals/pagination Traverse large customer, enrolment, transaction, card, and webhook collections safely. List endpoints use cursor pagination. A response has this shape: ```json theme={null} { "data": [], "has_more": true, "next_cursor": "cmexample", "limit": 100 } ``` Pass `next_cursor` back as `cursor`: ```bash theme={null} curl "$PERKSTAR_API_URL/customers?limit=100&cursor=cmexample" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" ``` ## Rules * Treat cursors as opaque strings. Do not parse or increment them. * Stop when `has_more` is false or `next_cursor` is null. * Keep the same filters while following a cursor. * Process each page before requesting the next one to avoid memory spikes. * Checkpoint the last completed cursor in long-running backfills. * Make your destination writes idempotent because records can change during a scan. Cursor pagination is not a frozen database snapshot. For ongoing sync, store Perkstar record IDs and `updated_at` values, and use webhooks to react to new activity between reconciliation runs. ## TypeScript SDK The official SDK follows cursors automatically: ```ts theme={null} for await (const customer of perkstar.customers.list({ limit: 100 })) { await upsertCustomer(customer); } ``` # Security, privacy, and data handling Source: https://developers.perkstar.co.uk/fundamentals/security-privacy Understand Perkstar's security boundaries, privacy roles, retention rules, and integration responsibilities. This page is the technical data-handling summary for teams integrating with Perkstar. The [Privacy Notice](https://dashboard.perkstar.co.uk/privacy), [Data Processing Agreement](https://dashboard.perkstar.co.uk/dpa), and [sub-processor list](https://dashboard.perkstar.co.uk/dpa/sub-processors) are the governing documents. This page explains product behaviour; it is not legal advice and does not replace your own privacy, security, or regulatory review. ## Responsibility model ```mermaid theme={null} flowchart LR Customer["Cardholder"] --> Business["Business using Perkstar\nNormally the data controller"] Business --> Perkstar["Perkstar\nNormally the data processor"] Perkstar --> Provider["Approved sub-processors\nand enabled integrations"] Partner["Your integration"] <--> Perkstar Business --> Partner ``` For cardholder loyalty data, the business normally decides why data is processed, what is collected, which messages are sent, and which integrations are enabled. Perkstar normally processes that data for the business. Perkstar acts as controller for limited platform purposes such as account administration, billing, support, security, fraud prevention, and legal compliance. Your organisation is responsible for determining its role for data copied to or from its integration, documenting a lawful purpose, and honouring deletion, access, correction, consent, and objection requests. ## Data an integration can handle | Category | Typical fields | Minimise it by | | - | - | - | | Customer identity | Name, email, phone, date of birth, external reference | Requesting only the scopes and fields needed for the workflow | | Loyalty activity | Card, enrolment, balance, transaction, reward and redemption records | Storing Perkstar IDs instead of duplicating full profiles | | Consent | Marketing and ad-tracking flags, consent history | Treating flags as purpose-specific evidence, not blanket permission | | Location and commerce context | Location ID, amount, order or transaction reference | Sending stable references and required totals, not full baskets by default | | Credentials | API keys, OAuth access/refresh tokens, webhook secrets | Keeping secrets in a server-side secret manager and never in client code | | Operational metadata | Request IDs, status codes, delivery IDs, timestamps | Avoiding raw payloads in logs unless needed and access-controlled | ## Security boundaries Credentials resolve to one organisation. Resource queries and mutations are checked against that organisation at the API boundary. API keys and OAuth grants carry explicit scopes. Create a separate credential for each integration and environment. API keys, client secrets, authorization codes, and OAuth tokens are stored as non-reversible hashes where they only need comparison. Provider credentials that must be reused are encrypted. Production traffic uses HTTPS. OAuth redirect URIs match exactly; webhooks are HMAC signed and outbound URLs are checked against private-network and DNS-rebinding targets. POST requests use idempotency keys, POS transactions support permanent external-reference deduplication, and OAuth refresh tokens rotate once. API responses include `X-Request-Id`; authenticated API activity is kept in a bounded audit trail for investigation and support. ## Credential handling 1. Create separate test and live credentials. 2. Grant only the scopes required by the job. 3. Store plaintext secrets immediately; Perkstar cannot reveal them again. 4. Never place a key or client secret in browser JavaScript, a mobile bundle, source control, analytics, screenshots, or support messages. 5. Rotate on suspected exposure and revoke credentials when an integration is disconnected. 6. Treat webhook bodies and OAuth tokens as personal or confidential data when they can be linked to a customer or business. See [Authentication and scopes](/fundamentals/authentication) and the [OAuth marketplace guide](/guides/oauth-marketplace) for implementation details. Businesses preparing to use the no-code connector should also read [Zapier data and security](/integrations/zapier/data-security) for its specific downstream data flow and deletion boundaries. ## Consent and communications Customer profile fields and consent flags can be written by an authorised integration. Perkstar records each real API consent transition, including the calling credential and request context, in its consent audit trail. That event records what the integration asserted; it does not prove that your external system collected valid consent. Keep the source, wording, time, and lawful basis needed for your own audit. Marketing wallet pushes require push-marketing consent. Transactional wallet updates needed to keep a pass accurate are separate from promotional communications. Do not infer email or SMS permission from a wallet install. ## Retention and deletion | Record | Current operational rule | | - | - | | Active customer profile | Kept while the operator account and loyalty relationship are active | | Cancelled-account cardholder data | 90-day grace period, then anonymised or deleted where no legal hold applies | | Pseudonymised transaction residue | Up to the applicable accounting/legal period, usually up to six years for UK operators | | Data-export archive | Expires after 48 hours and uses a single-use link | | Security and rate-limit logs | Normally 90 days unless required for an investigation | | API request audit | Rolling seven-day operational window | | Production backups | Rolling seven days | | Marketing suppression evidence | Kept as needed to prevent accidental re-contact | Customer erasure is implemented as anonymisation when financial or audit facts must remain. Direct identifiers are removed while the minimum pseudonymised ledger can be retained. `DELETE /customers/{id}` exposes that workflow to a properly scoped integration. Deleting data from your integration does not delete it from Perkstar, and anonymising it in Perkstar does not automatically erase an uncontrolled copy in your system. Design and test propagation in both directions. ## Webhook and OAuth data * Verify webhook signatures against the exact raw body before parsing. * Deduplicate with the stable webhook event ID and restrict access to stored delivery payloads. * OAuth access tokens expire after one hour. Refresh tokens rotate and must be replaced atomically; replay revokes the grant. * Revoking either an access or refresh token revokes the paired grant. * A marketplace uninstall should stop jobs, revoke tokens, remove unnecessary cached personal data, and retain only the audit facts your policy requires. ## Rights requests and incidents Businesses can export and anonymise customer data in the dashboard, and customers can use the privacy controls linked from their pass. Integration teams should be able to locate records by Perkstar ID and external reference, export a readable copy, correct a mismatch, and erase or suppress downstream copies. Report suspected credential exposure, unauthorised access, or a personal-data incident immediately to [privacy@perkstar.co.uk](mailto:privacy@perkstar.co.uk). For API implementation support, contact [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the relevant `X-Request-Id`, never a secret. ## Production review * [ ] Data flow, role, purpose, and lawful basis are documented. * [ ] Test data is separated from live credentials and jobs. * [ ] Secrets are stored server-side and rotation is tested. * [ ] Webhook verification, deduplication, and retention are tested. * [ ] OAuth disconnect and refresh-token replay are handled. * [ ] Customer export, correction, deletion, and suppression propagate. * [ ] Logs redact secrets and unnecessary personal data. * [ ] The DPA and sub-processor list have been reviewed. # Test mode Source: https://developers.perkstar.co.uk/fundamentals/test-mode Exercise an integration without changing live customer balances or configuration. Test mode uses a `pk_test_` key or an OAuth application registered in TEST mode. It shares the production API shape, but write behaviour is deliberately narrow. ## What a test key can do * Read cards, locations, customers, enrolments, transactions, and webhook configuration. * Create test ledger transactions against an existing enrolment. * Call `/marketplace/accrue` for an existing customer and existing enrolment. * Simulate wallet pushes without delivering a notification. * Receive signed transaction webhooks marked with `testMode: true`. * List and clean up test transactions. ## What it cannot do * Create, update, or anonymise a live customer. * Create or change a live enrolment. * Create, edit, or delete webhook configuration. * Use `/marketplace/enroll`. * Create a customer or enrolment as a side effect of `/marketplace/accrue`. * Deliver a real wallet push. These restrictions apply on the server even if an older key row contains an unsafe scope. The dashboard also removes unsupported scopes when a test key is created or edited. ## Testing a POS transaction 1. Use `GET /customers` or a scanned `card_serial` to resolve a customer. 2. Use `GET /enrollments` to find the matching card enrolment. 3. Post the transaction with a stable `external_transaction_id`. 4. Confirm the response includes `test_mode: true`. 5. Confirm your webhook receiver branches on `testMode`. Prefix test transaction references with `test:`. The same permanent reference cannot be reused later for a live transaction. To remove all test ledger rows after certification: ```bash theme={null} curl --request DELETE \ "https://dashboard.perkstar.co.uk/api/v1/transactions/test" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" ``` Test reads return the business's current records so an integration can prove its matching logic. Treat test keys as sensitive because those records can contain personal data. # Synchronise customers Source: https://developers.perkstar.co.uk/guides/customer-sync Match customer records without duplicates and preserve consent correctly. Use a stable upstream identifier whenever possible. Email addresses and phone numbers can change, be shared, or be entered differently across systems. ## Identity strategy `external_ref` is unique within a Perkstar business. Namespace the value when more than one source or account can produce the same native ID: ```text theme={null} odoo:company_4:partner_981 shopify:shop_12:customer_981 ``` When `POST /customers` includes an `external_ref`: * an existing match is returned with `200` and is not overwritten; * a missing match is created with `201`; and * retries remain safe beyond the request idempotency window. ## Initial import 1. Page through the source system in stable order. 2. Upsert each customer with `external_ref`. 3. Store the returned Perkstar customer ID in the source system. 4. Checkpoint progress after each completed page. 5. Run a second pass for records changed during the import. Limit concurrency and respect Perkstar's rate-limit headers. A large import should use a durable job queue, not one browser request. ## Consent Consent is not a convenience flag. Set `consent_marketing` or `consent_ad_tracking` only when the source system contains a valid, auditable permission for that purpose. A blank source value should not become `true`. ## Updates and deletion * Send PATCH only for fields your integration owns. * Normalise upstream phone numbers before matching where possible. * Treat a Perkstar anonymisation response as permanent. * Do not recreate an anonymised person automatically from a stale export. * Keep API keys and personal payloads out of logs. Test keys can read customer records but cannot create, edit, or anonymise them. Perform customer writes only after certification with a live key that has `CUSTOMERS_WRITE`. # Build an OAuth marketplace app Source: https://developers.perkstar.co.uk/guides/oauth-marketplace Implement installation, consent, token rotation, revocation, and reconnect for a multi-merchant Perkstar integration. Use OAuth when one application will be installed by multiple Perkstar businesses. Each merchant approves access to one organisation; your backend receives a scoped, short-lived access token and a rotating refresh token. ```mermaid theme={null} sequenceDiagram participant M as Merchant participant A as Partner app participant P as Perkstar OAuth participant API as Perkstar API M->>A: Select Install Perkstar A->>A: Create state + PKCE verifier A->>P: GET /oauth/authorize P->>M: Sign in, choose business, review scopes M->>P: Allow P-->>A: callback?code=...&state=... A->>P: Exchange code + verifier P-->>A: Access token + rotating refresh token A->>API: Bearer perk_at_... API-->>A: Organisation-scoped response ``` ## Supported profile | Capability | Perkstar behaviour | | - | - | | Authorization flow | Authorization Code | | PKCE | Required, `S256` only | | Access token lifetime | 3,600 seconds | | Refresh tokens | Single-use rotation; replay revokes the grant | | Redirect URIs | Exact match; HTTPS except loopback development callbacks | | Client authentication | HTTP Basic or form secret for confidential apps | | Merchant approver | Organisation owner or manager | | Revocation | RFC 7009-style endpoint; unknown tokens still return `200` | Perkstar does not support an implicit flow or a marketplace `client_credentials` grant. A merchant must approve access to their business. ## 1. Register the application Marketplace applications are reviewed and registered by Perkstar. Send [support@perkstar.co.uk](mailto:support@perkstar.co.uk): * application name, description, and HTTPS icon URL; * exact development, staging, and production redirect URIs; * the minimum scopes required; * a security/support contact and uninstall URL; and * whether the application is ready for test or live merchants. Perkstar returns a `client_id` and shows the `client_secret` once. Store the secret in your backend's secret manager. Dynamic client registration at `/api/oauth/register` is reserved for read-only MCP clients and cannot register a marketplace app or request REST API scopes. ## 2. Create state and PKCE Create a fresh verifier, challenge, and state for every install attempt. Store the verifier and state in a short-lived, single-use server-side record tied to the browser session. ```ts TypeScript theme={null} import { createHash, randomBytes } from "node:crypto"; const base64url = (value: Buffer) => value.toString("base64url"); const verifier = base64url(randomBytes(48)); const challenge = createHash("sha256").update(verifier).digest("base64url"); const state = base64url(randomBytes(32)); ``` ```python Python theme={null} import base64 import hashlib import secrets def b64url(value: bytes) -> str: return base64.urlsafe_b64encode(value).rstrip(b"=").decode() verifier = b64url(secrets.token_bytes(48)) challenge = b64url(hashlib.sha256(verifier.encode()).digest()) state = b64url(secrets.token_bytes(32)) ``` ## 3. Send the merchant to consent ```text theme={null} https://dashboard.perkstar.co.uk/oauth/authorize ?response_type=code &client_id=oac_replace_me &redirect_uri=https%3A%2F%2Fintegration.example.com%2Foauth%2Fperkstar%2Fcallback &scope=CUSTOMERS_READ%20ENROLLMENTS_READ%20TRANSACTIONS_WRITE &state=random_single_use_state &code_challenge=base64url_sha256_challenge &code_challenge_method=S256 ``` The merchant signs in, chooses an organisation they own or manage, and sees the requested permissions. Perkstar does not redirect to an unregistered URI when the request is invalid. ## 4. Validate the callback On success, Perkstar redirects to the exact registered URI with `code` and the original `state`. On denial it returns `error=access_denied` and the state. 1. Compare `state` in constant time with the stored, unused value. 2. Refuse missing, mismatched, expired, or already-used state. 3. Mark the install attempt consumed before exchanging the code. 4. Never log the authorization code or callback query string. Authorization codes are short-lived and single-use. A duplicate or delayed callback must start a fresh install. ## 5. Exchange the code The token endpoint accepts form-encoded bodies, not JSON. ```bash theme={null} curl --request POST https://dashboard.perkstar.co.uk/api/oauth/token \ --user "$PERKSTAR_CLIENT_ID:$PERKSTAR_CLIENT_SECRET" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=authorization_code" \ --data-urlencode "code=$PERKSTAR_AUTHORIZATION_CODE" \ --data-urlencode "redirect_uri=https://integration.example.com/oauth/perkstar/callback" \ --data-urlencode "code_verifier=$PERKSTAR_CODE_VERIFIER" ``` ```json theme={null} { "access_token": "perk_at_example", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "perk_rt_example", "scope": "CUSTOMERS_READ ENROLLMENTS_READ TRANSACTIONS_WRITE", "organization_id": "org_123" } ``` Store the organisation ID with the grant and enforce one active installation record per `(application, organization_id)` in your system. ## 6. Call the API ```bash theme={null} curl https://dashboard.perkstar.co.uk/api/v1/marketplace/ping \ --header "Authorization: Bearer $PERKSTAR_ACCESS_TOKEN" ``` Treat a `401` as an authentication problem, not permission to switch to another merchant's token. A `403` means the authenticated grant, scope, plan, or account state does not permit that action. ## 7. Rotate refresh tokens atomically Every successful refresh invalidates the supplied refresh token and returns a new one. Use a lock or compare-and-swap around the installation row. ```bash theme={null} curl --request POST https://dashboard.perkstar.co.uk/api/oauth/token \ --user "$PERKSTAR_CLIENT_ID:$PERKSTAR_CLIENT_SECRET" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=refresh_token" \ --data-urlencode "refresh_token=$PERKSTAR_REFRESH_TOKEN" ``` Ensure two workers cannot refresh the same grant concurrently. Send the token stored on the locked row. Do not retry an ambiguous refresh concurrently from another worker. Replace the access token, refresh token, expiry, and scopes in one database transaction before releasing the lock. Refresh-token replay revokes the chain. Stop background jobs and send the merchant through authorization again; do not loop retries. ## 8. Revoke and uninstall ```bash theme={null} curl --request POST https://dashboard.perkstar.co.uk/api/oauth/revoke \ --header "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "client_id=$PERKSTAR_CLIENT_ID" \ --data-urlencode "client_secret=$PERKSTAR_CLIENT_SECRET" \ --data-urlencode "token=$PERKSTAR_REFRESH_TOKEN" \ --data-urlencode "token_type_hint=refresh_token" ``` Revoking either token revokes the pair. After a successful uninstall: * stop polling, queue drains, and webhook side effects for the merchant; * remove active credentials from normal application storage; * delete copied personal data that is no longer required; * retain only the minimum audit or legal record required by your policy; and * make reinstall create a fresh grant rather than reviving old credentials. Merchants can also revoke access in **Settings → Connected apps**. Your jobs must handle that without relying on your own uninstall screen being called. ## Error handling | Error | Meaning | Partner action | | - | - | - | | `invalid_request` | Missing parameter or wrong content type | Correct the request; do not retry unchanged | | `invalid_client` | Client ID/secret failed | Stop and check configuration or secret rotation | | `invalid_grant` | Code/token expired, used, revoked, mismatched, or replayed | Start a fresh merchant authorization | | `invalid_scope` | No still-allowed scope remains | Review app registration and requested scopes | | `unsupported_grant_type` | Flow is not authorization code or refresh token | Correct the implementation | | `temporarily_unavailable` | Rate-limit or transient gate | Honour backoff and retry safely | ## Launch checklist * [ ] Redirect URIs are exact and environment-specific. * [ ] State and PKCE are fresh, server-stored, expiring, and single-use. * [ ] Client secrets and tokens never reach browser or mobile code. * [ ] Refresh replacement is atomic and concurrency-tested. * [ ] `invalid_grant`, merchant denial, and revocation lead to a clear reconnect state. * [ ] Jobs are pinned to the stored `organization_id`. * [ ] Uninstall removes credentials and unnecessary cached personal data. * [ ] Test and live application credentials are separated. * [ ] The [security and privacy review](/fundamentals/security-privacy) is complete. # Connect Odoo Source: https://developers.perkstar.co.uk/guides/odoo A production pattern for syncing Odoo contacts and POS orders with Perkstar. Build the connector as an Odoo server module or trusted middleware service. Do not call Perkstar directly from browser-side Odoo code because that would expose the API key. ## Recommended mapping | Odoo | Perkstar | Rule | | - | - | - | | Company + `res.partner.id` | `customer.external_ref` | `odoo::partner:` | | POS order ID | `external_transaction_id` | `odoo::pos_order:` | | POS location | `metadata.locationId` | Store the Perkstar location UUID on the Odoo shop config | | Loyalty programme | `card_id` | Explicit mapping; do not infer when several cards exist | | Refund ID | reversal idempotency key | One stable key per refund operation | ## Contact sync When an Odoo contact becomes eligible for loyalty, call `POST /customers` with `external_ref`. That endpoint upserts on the external reference: a retry returns the existing customer without overwriting it. ```json theme={null} { "external_ref": "odoo:4:partner:981", "email": "customer@example.com", "first_name": "Amina", "last_name": "Khan" } ``` Keep Odoo as the source of truth only for fields the business has deliberately chosen to sync. Do not overwrite consent flags from a generic contact import. ## Order completion On a paid or completed POS order, call `/marketplace/accrue`. Send: * the mapped `card_id`; * the Odoo partner external reference; * the stable POS order reference; * `amount_pence` when the card earns from spend; and * the mapped Perkstar `locationId`. Use Odoo's post-commit or job queue mechanism. If an Odoo transaction later rolls back, it must not leave a loyalty award behind. ## Refunds and cancellations On a confirmed refund, call `/marketplace/reverse` with the original external transaction reference. Record the returned Perkstar reversal ID on the refund record so support can trace both sides. ## Reconciliation job Run a scheduled reconciliation that: 1. finds completed Odoo orders missing a Perkstar transaction ID; 2. retries them with the original idempotency and transaction references; 3. compares recent Perkstar transactions with Odoo orders; and 4. alerts on unmatched or terminal failures. Webhooks make the integration responsive; reconciliation makes it reliable. ## Go-live sequence 1. Develop with a test key and existing Perkstar enrolment. 2. Verify test webhooks and duplicate delivery handling. 3. Test a timeout followed by a retry. 4. Test a full and partial Odoo refund policy with the business. 5. Create a new narrowly scoped live key. 6. Process one low-risk live order and confirm the wallet update. 7. Enable the connector location by location. # Build a POS integration Source: https://developers.perkstar.co.uk/guides/pos Walk through a complete till journey: connect, identify, earn, display, reverse, and reconcile. Start with [one tested stamp request and webhook receipt](/quickstart) before building a complete POS adapter. This walkthrough models the customer and cashier journey as well as the API calls behind it. It uses the marketplace endpoints because one request can resolve the customer, select the programme, find or create the enrolment, and post loyalty safely. Confirm the business and choose the exact card and location. Scan or match the customer, then accrue loyalty with durable IDs. Reverse refunds, retry timeouts, and reconcile missed events. ## Choose the installation model Create a dedicated API key in that business's dashboard. This is the simplest model for an in-house connector, one Odoo database, or one POS merchant. Grant `MARKETPLACE`, plus `LOCATIONS_READ` when the integration maps stores. Add separate read scopes only for reconciliation jobs that need them. Use OAuth when the same application will be installed by many businesses. Each merchant consents to one organisation and your backend stores a separate token set for it. Follow the [OAuth marketplace guide](/guides/oauth-marketplace) before implementing this walkthrough. Start with a `pk_test_...` key. Test writes create isolated ledger rows but do not alter live balances, wallet passes, or analytics. Test mode cannot create live customers or enrolments, so prepare an existing enrolment first. ## The till journey ```mermaid theme={null} sequenceDiagram participant C as Customer wallet participant T as Till / POS participant P as Perkstar API participant B as Partner backend C->>T: Present wallet barcode T->>B: Raw scanned value + basket reference B->>P: POST /marketplace/accrue P->>P: Resolve customer, card, enrolment P->>P: Deduplicate external transaction P-->>B: Customer + enrolment + transaction B-->>T: Loyalty applied / reward state P-->>C: Wallet pass refresh Note over B,P: Webhooks + scheduled reconciliation keep both systems aligned ``` ## Step 1: confirm the installation ```bash theme={null} curl "$PERKSTAR_API_URL/marketplace/ping" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" ``` Persist the returned organisation ID, currency, timezone, key mode, and card choices. If `default_card_id` is `null`, the business has more than one active card. Ask the operator to map each till programme or location to a specific `card_id`; never select the first result silently. A credential belongs to one Perkstar organisation. If the response names a different business from the one your installation expects, stop setup rather than writing to it. ## Step 2: map stores and programmes Use `GET /locations` with `LOCATIONS_READ` to resolve Perkstar location IDs. Store a mapping instead of comparing display names. | POS concept | Perkstar value | Rule | | - | - | - | | Merchant/account | Organisation ID from `marketplace/ping` | Immutable installation owner | | Loyalty programme | `card_id` | Explicit when several cards are active | | Store/site | `location_id` | Map once, refresh when configuration changes | | Order/payment | `external_transaction_id` | Stable and permanently unique for the business | | Request attempt | `Idempotency-Key` | Reuse for every retry of the same operation | ## Step 3: identify the customer Perkstar resolves identifiers in a fixed priority. Send only identifiers that belong to the same person. ```json theme={null} { "identifier": { "customer_id": "cus_123" } } ``` Map this opaque ID from an earlier Perkstar API or Zapier step. It is scoped to the connected business. An unknown ID returns `404` and never creates a replacement customer from the ID alone. ```json theme={null} { "identifier": { "card_serial": "exact-value-returned-by-the-scanner" } } ``` Pass the scanned content unchanged. Current opaque POS identifiers and older numeric/serial formats are supported. Do not parse, group, truncate, convert case, or assume a fixed length. ```json theme={null} { "identifier": { "external_ref": "odoo:company_4:partner_981" } } ``` Namespace stable IDs with the provider and account so two merchants cannot accidentally generate the same local reference. ```json theme={null} { "identifier": { "email": "alice@example.com" } } ``` Use contact details only when the POS has collected them legitimately. An email match is case-insensitive; phone matching prefers normalised E.164 and retains the stored raw value as a compatibility fallback. Resolution order is `customer_id`, `card_serial`, first-party provider identity, `external_ref`, email, then phone. The first match wins. ## Step 4: add loyalty ```bash theme={null} curl --request POST "$PERKSTAR_API_URL/marketplace/accrue" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: odoo:company_4:order_94721:loyalty" \ --data '{ "identifier": { "card_serial": "value-from-scanner" }, "card_id": "card_123", "transaction": { "type": "STAMP", "delta": 1, "external_transaction_id": "odoo:company_4:order_94721", "metadata": { "locationId": "location_123" } } }' ``` Send `type: "STAMP"` and the number of stamps in `delta`. Most integrations send `1` after an eligible completed sale or visit. Send the qualifying amount in `amount_pence`. Perkstar applies the card's current points rule. Send an explicit `delta` only when the upstream system is contractually authoritative for the points amount. Use `ADJUST` only for an intentional correction with a useful note. A refund should use reversal so the audit trail remains linked. Two safety keys protect the operation: * `Idempotency-Key` replays the same HTTP result during the request-cache window; and * `external_transaction_id` permanently prevents the same POS sale from earning twice. Use both and choose a namespace owned by your integration, such as `odoo::order:`. Provider-managed prefixes such as `sq_payment_` are reserved and return `400 reserved_external_transaction_id`. A timeout does not prove the write failed. ## Step 5: update the till Use the returned customer, enrolment, balance, and transaction to show a short, stable result without making another request. Loyalty was applied for the first time. Store the returned transaction ID beside the POS order/payment reference. The permanent external reference already existed. Treat this as a safe replay, not a second award. Test credentials cannot create a live customer or enrolment. Select an existing testable customer and card, then retry. The supplied identity or external transaction conflicts with an existing record or environment. Stop and surface a staff-review state; do not invent another identifier. Honour `Retry-After` for `429`. Retry transient failures with backoff and the same idempotency and external transaction IDs. ## Step 6: reverse a refund or void ```bash theme={null} curl --request POST "$PERKSTAR_API_URL/marketplace/reverse" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: odoo:company_4:refund_301" \ --data '{ "external_transaction_id": "odoo:company_4:order_94721", "reason": "POS order refunded" }' ``` Reversal writes a compensating transaction linked to the original. Replaying a refund returns the existing reversal. Do not create an unrelated negative award: it loses the original-sale link and weakens reconciliation. ## Step 7: work through outages ```mermaid theme={null} flowchart TD A["POS operation"] --> B{"Perkstar response received?"} B -- Yes --> C{"Accepted or permanent error?"} C -- Accepted --> D["Store Perkstar transaction ID"] C -- Permanent error --> E["Show staff-review state"] B -- No --> F["Queue locally with original IDs and occurred time"] F --> G["Retry with backoff and the same IDs"] G --> B ``` An offline queue should retain the original merchant, card, location, customer identifier, transaction reference, idempotency key, amount, and occurrence time. Encrypt local data, bound retention, and make failed entries visible to staff. ## Step 8: reconcile Webhooks provide fast updates; scheduled reads prove eventual consistency. 1. Subscribe to `transaction.created`, `customer.enrolled`, `reward.redeemed`, and `tier.changed` as relevant. 2. Verify and persist each event before acknowledging it. 3. At least daily, compare recent POS references with Perkstar transactions. 4. Repair missing writes using the same stable IDs. 5. Alert on a queue that is old, repeatedly failing, or growing unexpectedly. See the [webhook catalogue](/reference/webhook-events) for exact payloads. ## Go-live proof * [ ] Installation identifies the expected organisation. * [ ] Every store and loyalty programme is mapped explicitly. * [ ] Old and current wallet barcode formats resolve unchanged. * [ ] Replaying a sale never awards twice. * [ ] A timeout followed by retry converges on one transaction. * [ ] Full refund creates one linked reversal. * [ ] Test traffic cannot change a live customer balance. * [ ] Offline work survives restart and has a visible failure state. * [ ] Webhook signatures and event deduplication are tested. * [ ] Reconciliation finds and repairs a deliberately skipped event. # Send push notifications Source: https://developers.perkstar.co.uk/guides/wallet-pushes Send a customer-safe wallet push or simulate delivery in test mode. `POST /pushes` sends a push notification to the wallet pass attached to a specific enrolment. The customer must have push marketing consent and an active eligible card. ```bash theme={null} curl --request POST "$PERKSTAR_API_URL/pushes" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: summer-reminder-enrolment_123" \ --data '{ "enrollment_id": "enrolment_123", "message": "Hi {firstName}, your {cardName} is ready for your next visit." }' ``` ## Merge fields The message can use: * `{firstName}` * `{balance}` * `{installLink}` * `{shareLink}` * `{cardName}` * `{orgName}` Keep the message useful without relying on a field that may be blank. Preview the final wording in the dashboard before automating it. ## Delivery behaviour * A three-minute cooldown applies per card across dashboard and API sends. * `429` includes `Retry-After` when the cooldown or key limit is hit. * The response reports attempted and failed platforms. * Test credentials return `test_mode: true` without delivering or writing a broadcast row. * A successful API response means Perkstar handed the update to the wallet platform; device display is controlled by Apple or Google. Balance changes and reward events have their own service notifications and wallet refresh pipeline. Use this endpoint for business-authored messages, not as a replacement for posting the underlying loyalty transaction. ## Safe automation * Send only when the workflow has a clear customer purpose. * Respect consent and suppression state returned by Perkstar. * Use one idempotency key per intended message. * Do not include health data, payment details, passwords, or other sensitive information. * Rate-limit upstream triggers so a bulk sync cannot notify the same customer repeatedly. The public Perkstar app for Zapier exposes this operation as **Send Wallet Push**. See the [Zapier catalogue](/integrations/zapier/triggers-actions) for its mapping and [Zapier data and security](/integrations/zapier/data-security) before sending a marketing message through a Zap. # Receive webhooks Source: https://developers.perkstar.co.uk/guides/webhooks Verify signed Perkstar events, handle retries, and reconcile missed deliveries. Webhooks notify your server when loyalty activity changes. Use them for fast updates, then run periodic reconciliation so one delayed delivery cannot leave systems permanently out of sync. Building a Zap with the official Perkstar app? Follow [Connect Perkstar to Zapier](/integrations/zapier/setup). Zapier creates, deletes, and recreates its own event-specific subscriptions; you do not need to paste a Catch Hook URL into Perkstar for the same trigger. ## Create an endpoint Create webhook configuration with a narrowly scoped live key or in the dashboard. The plaintext signing secret is returned once. ```bash theme={null} curl --request POST "$PERKSTAR_API_URL/webhooks" \ --header "Authorization: Bearer $PERKSTAR_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: webhook-primary-v1" \ --data '{ "url": "https://integration.example.com/webhooks/perkstar", "events": ["transaction.created", "customer.enrolled"], "card_id": "card_123", "mode": "live" }' ``` Store the returned secret in the receiving service's secret manager before the response is discarded. Common event names include: * `customer.enrolled`, `customer.unenrolled`, `customer.anonymized`, `customer.group_changed` * `wallet.installed`, `card.scanned`, `card.expired`, `referral.created` * `transaction.created`, `reward.redeemed`, `coupon.redeemed`, `tier.changed` * `membership.purchased`, `membership.renewed`, `membership.cancelled` * `booking.created`, `booking.attended`, `booking.no_show`, `booking.cancelled` * `webhook.test` The [complete event catalogue](/reference/webhook-events) documents every supported event, its exact `data` fields, and an example payload. Subscribe only to events your receiver handles. An empty `events` array subscribes the endpoint to all events. `card_id` is optional and excludes events for every other card before delivery; events without a matching card are also excluded. `mode` accepts `live`, `test`, or `all` and defaults to `all` for backward compatibility. These filters avoid creating delivery rows or outbound requests that the receiver would discard. Some merchant events represent an observed state rather than a synchronous API write. Recently issued Google Wallet passes are eligible for observation on a 15-minute schedule, but provider cadence, object age, and projector backlog can extend the delay. Card scans cover successful online Perkstar Scanner lookups only. Card expiry is per enrolment and effective expiry instant, and lifecycle-group changes do not represent membership in saved segments. See each event's boundary in the catalogue before designing a workflow. When a business enables its first endpoint for `customer.group_changed` or Google `wallet.installed`, allow one completed projection sweep for Perkstar to store the current state without replaying historical customers or installs. Tracking starts after that warm-up baseline. Apple installation is callback-driven and does not use this warm-up. ## Event envelope Every request body uses the same envelope: ```json theme={null} { "id": "whd_01JEXAMPLE", "type": "transaction.created", "created": 1785312000, "orgId": "org_123", "data": { "transactionId": "txn_123", "enrollmentId": "enr_123", "type": "STAMP", "delta": 1, "occurredAt": "2026-07-30T10:00:00.000Z" } } ``` `id` is stable across automatic retries. For business events, `created` is the source event's `data.occurredAt` time expressed as Unix seconds, so it also remains stable. Deduplicate with `id`; do not use either timestamp as an identity key. Perkstar also sends: | Header | Purpose | | - | - | | `X-Perkstar-Event` | Dotted event name | | `X-Perkstar-Webhook-Id` | Configured endpoint ID | | `X-Perkstar-Delivery-Id` | Stable logical delivery ID; matches body `id` | | `X-Perkstar-Timestamp` | Unix time for this signing and delivery attempt | | `X-Perkstar-Signature` | `t=...,v1=...` HMAC signature | For a complete runnable test receiver, persistence example and expected-result checklist, follow [Your first safe POS test](/quickstart#4-receive-a-signed-test-event). ## Verify before parsing Perkstar sends a Stripe-style signature: ```http theme={null} X-Perkstar-Signature: t=1785312000,v1= ``` The signed value is `.`. Verify the raw bytes and a five-minute timestamp tolerance before trusting or parsing the JSON. ```ts theme={null} import { verifyWebhookSignature } from "@perkstar/api-client/webhooks"; const rawBody = await request.text(); const event = verifyWebhookSignature({ payload: rawBody, signature: request.headers.get("x-perkstar-signature") ?? "", secret: process.env.PERKSTAR_WEBHOOK_SECRET!, }); await processOnce(event.id, event); return new Response(null, { status: 200 }); ``` Reading JSON first and serialising it again changes the signed bytes. Capture the raw body before any framework body parser runs. ## Processing rules 1. Verify the signature and timestamp. 2. Deduplicate by event ID in your database. 3. Persist or enqueue the event before returning `2xx`. 4. Process asynchronously when work could exceed a few seconds. 5. Make handlers safe when events arrive twice or out of order. 6. Branch test traffic using `testMode: true`. Return a non-`2xx` status only when a retry may help. Validation failures should be recorded for operator review rather than retried forever. ## Delivery schedule Perkstar considers any `2xx` response successful. Network errors, timeouts, and non-`2xx` responses are retried on this schedule: | Attempt | Timing | | - | - | | 1 | Immediately | | 2 | 1 minute after the first failure | | 3 | 5 minutes after the second failure | | 4 | 30 minutes after the third failure | After four failed attempts, the delivery is marked exhausted and remains available in the dashboard for inspection and manual resend. Keep each request under ten seconds and acknowledge after durable persistence, before expensive downstream work. HTTP `410 Gone` is the exception to the retry schedule. Perkstar treats it as a permanently removed callback, exhausts the current delivery immediately, and pauses the endpoint so future events are not sent to a dead destination. Automatic retries keep the same logical delivery `id`. A dashboard **Resend** preserves that same logical ID. A receiver that has already committed the event should acknowledge the duplicate without repeating its business action. If your own downstream processing failed after receipt, retry it from your durable inbox; a Perkstar resend must not bypass your deduplication protection. ## Test and operate the endpoint In **Dashboard → Settings → Webhooks**, open the endpoint to: * send a targeted `webhook.test` event while the endpoint is active; * inspect attempt status, response code, duration, and the retained response excerpt; * resend a failed or exhausted delivery after fixing the receiver; * pause the endpoint without deleting its configuration; * rotate the signing secret and update the receiver immediately; or * remove the endpoint and its delivery history. Production endpoint URLs must use HTTPS and resolve only to public network addresses. Perkstar blocks localhost, private/reserved IP ranges, and DNS rebinding targets. ## Recent event feed `GET /events` returns one canonical source event regardless of how many endpoints received it. It requires the dedicated `EVENTS_READ` permission, defaults to live records, supports dotted event, card, customer, time, and live/test filters, and retains rows for 90 days. This permission is separate from `WEBHOOKS_READ` so an existing key that can inspect endpoint configuration does not automatically gain customer event payload access. Use the feed for setup samples and bounded reconciliation. It is not a polling replacement for an instant subscription and it does not reveal signing secrets or internal event-deduplication keys. ## Reconciliation At least daily, compare the external system with recent Perkstar transactions or customers. Webhooks provide speed, while reconciliation catches exhausted retries, downtime, and deployment mistakes. # Perkstar developer platform Source: https://developers.perkstar.co.uk/index Connect POS, CRM, commerce, and back-office systems to Perkstar loyalty. Build loyalty into the systems a business already uses. The Perkstar API lets an integration find or create customers, enrol them onto cards, add stamps or points, reverse mistakes, send wallet pushes, and receive signed webhooks. Create a key, confirm the connection, and inspect your first response. Scan a wallet pass, credit loyalty, and reverse a refunded sale safely. Map customers and orders without duplicating records or rewards. Use the generated reference, request builder, and response schemas. Run every public operation with safe variables and built-in checks. Install with OAuth, rotate tokens safely, and handle disconnects. See available connections and follow merchant-friendly setup guides. Use the public Perkstar app for 29 instant triggers, 10 scoped actions, guided searches, and self-serve setup through OAuth. Preview one dynamic instant trigger for 29 loyalty events, 11 guided actions, two searches, and a universal API module in the private beta. Use Perkstar's read-only MCP server with automatic OAuth discovery. See live API, scanner, wallet, webhook, billing, and POS health. Connect Resend for customer invitations and card-install links, with a verified delivery test. ## Designed for production * **Scoped access.** Each key can do only the jobs you select. * **Safe retries.** Idempotency keys prevent a timeout from becoming a double stamp. * **Permanent POS deduplication.** Stable transaction references remain unique beyond the 24-hour request cache. * **Signed webhooks.** Verify every delivery before trusting its contents. * **Request tracing.** Every response includes an `X-Request-Id` that Perkstar support can trace. API access is available to eligible Perkstar plans. Create and manage keys in **Dashboard → Settings → API keys**. A secret is shown once, so store it in a server-side secret manager when it is created. ## Choose a starting point | You are building | Start here | | - | - | | A POS or till plugin | [POS integration](/guides/pos) | | An Odoo connector | [Odoo integration](/guides/odoo) | | A CRM or customer import | [Customer sync](/guides/customer-sync) | | A server that reacts to loyalty events | [Webhooks](/guides/webhooks) | | A no-code workflow in Zapier | [Perkstar on Zapier](/integrations/zapier) | | A visual scenario in Make | [Make private beta](/integrations/make) | | A public marketplace application | [OAuth marketplace app](/guides/oauth-marketplace) | | An AI assistant connection | [MCP server](/tools/mcp) | | A TypeScript or Node.js service | [TypeScript SDK](/sdks/typescript) | | A Python or Odoo service | [Python SDK](/sdks/python) | # Access EPoS Source: https://developers.perkstar.co.uk/integrations/access/index Availability and next steps for Access EPoS. **No self-service installation.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Connect Access hospitality locations when provider access and the production integration are released. This reference covers an existing or restricted connection. It is not an invitation to start a new connection. ## What to do now Open **Perkstar → Integrations** and inspect Access EPoS. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Acuity appointments and rewards Source: https://developers.perkstar.co.uk/integrations/acuity/appointments-rewards Understand customer matching, end-plus-15-minute attendance earning and one-time Acuity reward codes. Acuity supplies the appointment lifecycle. Perkstar matches the booking to an existing member, records attendance and controls the linked loyalty balance and reward state. ## Match the existing member Perkstar does not create customers or card enrolments from Acuity bookings. Matching happens when attendance is due, in this order: 1. Find one active Perkstar customer by an exact, case-insensitive email match. 2. If email does not resolve one customer, normalise the Acuity phone number using the business country and find one customer by phone. 3. Confirm that customer already has an active enrolment on the linked Stamp card. A name is stored only to help staff recognise the booking. It is never used to match a customer. An ambiguous email or phone, an unmatched contact, or a customer who has not joined the linked card does not earn. Ask the customer to join the correct Perkstar card before the appointment. An unmatched or not-enrolled attendance is not credited retrospectively, and Perkstar does not turn the Acuity contact into a new loyalty member. ## Appointment updates and attendance Perkstar maintains one signed `appointment.changed` subscription because [Acuity defines it as the catch-all event](https://developers.acuityscheduling.com/docs/webhooks) for scheduling, rescheduling, cancellation and detail changes. A daily reconciliation reads the relevant appointment window again to close gaps after a disabled webhook, provider error or deployment. Confirmed appointments are auto-marked attended after the **scheduled end plus 15 minutes**. Perkstar uses a deterministic attendance reference, so webhook retries, the daily reconciliation and repeated processing cannot credit the same appointment twice. ## How earning is calculated | Stamp card rule | Acuity attendance result | | - | - | | Visit-based | Awards the card's configured stamps per visit | | Spend-based | Applies the card's spend threshold and stamps using the Acuity appointment price | | Manual | Does not earn automatically because the booking has no staff-entered stamp amount | Spend-based earning requires the same currency in Acuity and Perkstar and a usable appointment price. A missing price does not invent a spend amount. Acuity's `paid` indicator is recorded for context but is not an attendance gate. A reserved or unpaid appointment can earn after attendance. Acuity states that [payment-processor refunds are not reflected in Acuity](https://help.acuityscheduling.com/hc/en-us/articles/28052155599885-Handling-refunds-and-price-adjustments), so they are not synchronised into Perkstar; use an Acuity cancellation or no-show when attendance should be corrected. When Square routes earning to this same Stamp card, Square is the earning owner, including while its connection temporarily needs reconnection. Acuity still shows the appointment and can issue or reconcile reward codes, but it skips attendance credit. Do not switch an established card's owner while appointment or payment events may still be in flight. ## Issue a one-time reward code Perkstar can provision codes for: * the normal completed-card reward; * a configured reward at a particular stamp milestone; and * the card's birthday reward, when it issues a reward rather than extra stamps. Perkstar confirms the reward is available on the linked card and selects the Acuity coupon, package, gift or subscription source mapped to that reward. The generated code is attached to that one Perkstar reward. Acuity applies the source's service restrictions, value, usage and expiry. Perkstar adds the code to the Wallet pass and sends the reward email when a deliverable customer email is available. A configured booking button opens Acuity with the code and customer booking details prefilled. On the default Stamp card layout, an available issued code replaces the **Earned rewards** count on the front with a **Code** field. The full reward list remains in Pass Details. Redeeming the code restores the normal reward count; an eligible cancellation makes the restored code visible again. Custom front-field layouts remain unchanged. The customer applies it in Acuity's package, gift or coupon field. Acuity permits one coupon or package-style code per appointment. When the appointment reports the managed code, Perkstar claims that exact reward once, removes the code from Wallet and queues the Wallet update. An unavailable or suppressed email does not make the reward disappear. Check the customer's current Wallet pass. If the reward should also be emailed, correct the customer email and follow the integration's retry guidance. ## What is retained Perkstar retains the provider appointment reference, schedule and duration, service and calendar/staff labels, appointment price and paid indicator, cancellation or no-show state, customer contact fields needed for matching, and whether a managed certificate was applied. Acuity intake-form answers, internal notes, payment card details and payment-processor transactions are not retained for this integration. For corrections and delayed activity, continue to [Cancellations and troubleshooting](/integrations/acuity/cancellations-troubleshooting). # Acuity cancellations and troubleshooting Source: https://developers.perkstar.co.uk/integrations/acuity/cancellations-troubleshooting Correct cancellations and no-shows, diagnose missing attendance or reward codes and disconnect Acuity safely. ## Cancellations and no-shows Record the real appointment outcome in Acuity. Perkstar reads the resulting appointment state through the managed webhook or daily reconciliation and applies the supported correction idempotently. | Acuity outcome | Attendance credit | Managed reward code | | - | - | - | | Normal cancellation before attendance | No credit is added | A code applied to the booking is restored when still eligible | | Normal cancellation after auto-attendance | The prior attendance credit is reversed | The applied code is restored when still eligible | | No-show before attendance | No attendance credit is added | The code remains consumed | | No-show after auto-attendance | The prior attendance credit is reversed | The code remains consumed | A provider cancellation or no-show remains authoritative even if delivery is late. Manual attendance corrections in Perkstar are limited to 72 hours. If the earned value has already been used or later activity makes reversal unsafe, Perkstar flags the booking for manual review instead of guessing. Do not make a manual stamp or reward adjustment while an Acuity correction is pending. The managed webhook or daily reconciliation may still apply the automatic reversal or restoration, causing a duplicate correction. An Acuity or payment-processor refund by itself does not change attendance or reverse stamps. Acuity is the source of the appointment outcome, not payment settlement. ## Troubleshooting New connections require Perkstar Growth or higher and an active Acuity account with the required API access. Sign in to Perkstar as an owner or manager. The Acuity owner or a Scheduling Administrator should authorise the connection so the OAuth user is not restricted to selected calendars. Check the subscription for the exact Acuity account connected to Perkstar. A saved Perkstar connection is not proof that its subscription or public scheduler is active. If you have already paid, check the account and invoice with Acuity support instead of purchasing again. Acuity documents Premium or Powerhouse for API credentials; verify **View credentials** access if Perkstar asks for a signing key. Once account access is working, complete a real booking-to-reward test before inviting customers to use it. In Acuity, open **Integrations → API → View credentials**. Copy the API key belonging to the same Acuity user who authorised Perkstar. Perkstar verifies the key and user ID with Acuity before saving it; a key from another user or account cannot verify this connection. Perkstar should maintain one `appointment.changed` subscription. Do not add a manual Perkstar webhook. Reconnect or save the verified API key again so Perkstar can inspect, remove stale managed subscriptions and restore the catch-all subscription. The daily reconciliation remains the recovery path, but the warning should still be resolved. Confirm it belongs to the connected Acuity account and a calendar visible to the user who authorised Perkstar. Check the integration account, timezone and last sync. Allow the daily reconciliation to close a transient webhook gap before recreating the appointment. Wait until the scheduled end plus 15 minutes. Confirm the linked Stamp card is active, the Acuity and Perkstar currencies match for spend earning, and no Square route owns earning for the same card. The Acuity contact must resolve uniquely by email or normalised phone to an existing Perkstar customer who is already enrolled on that card. A name-only match, missing enrolment or manual card rule does not earn. Interrupted loyalty writes are durably retried by the attendance worker; do not manually add a duplicate stamp while recovery is pending. A booking deliberately skipped because the customer was not enrolled is not credited retroactively by a duplicate delivery after they join. Reconciliation splits full results by date and calendar and checks both sorted ends of a dense day. If it still cannot prove that all appointments were returned, it reports the affected window while continuing other windows. Keep signed booking updates connected and contact support with the affected dates and calendar numbers; do not treat that sync as complete. Payment is not the attendance gate. A confirmed appointment can earn after its end even when Acuity reports it unpaid. Acuity and processor refunds do not sync into loyalty. Mark the appointment cancelled or no-show in Acuity when the attendance outcome should reverse the credit. Final reward appears for the Stamp card's completed-card reward. Milestone and birthday rows appear only when those rewards exist on that same card. Changing the attendance card disables codes and clears the previous card-specific mappings. Confirm online reward codes are enabled, the reward is mapped to a whole numeric Acuity source ID and the source still exists. Save the mappings, then use **Create existing codes** for eligible unclaimed rewards earned before setup. A code can remain on Wallet even when email delivery is unavailable or suppressed. Check the source's expiry, remaining use, eligible appointment types and value in Acuity. Only one coupon, package, gift or subscription code can be applied to an appointment. Do not replace the Perkstar-generated code with a reusable public coupon. Perkstar pauses automatic work rather than choosing an account. Contact [Perkstar support](mailto:support@perkstar.co.uk) to separate the connections safely. ## Disconnect safely Disconnect in Perkstar **before** revoking Perkstar from Acuity. Working Acuity access is required to remove managed certificates and the webhook subscription safely. Allow any displayed cancellation, no-show or certificate cleanup to finish and record the affected appointment numbers. Open **Settings → Integrations → Acuity** and choose **Disconnect Acuity**. Perkstar first retires managed Acuity certificates and removes its managed webhook subscription. Keep Acuity authorised. If Perkstar reports pending certificate or webhook cleanup, wait briefly and choose disconnect again rather than revoking the account first. Only after Perkstar reports the integration disconnected should you remove its access from Acuity. Disconnecting stops appointment sync and new automatic reward codes. Open bookings are unlinked from the attendance card, and managed codes are removed from Wallet as cleanup completes. Existing Perkstar customers, card enrolments, cards, completed booking records, transaction history and earned loyalty rewards remain under the normal retention rules. Already revoked Acuity access first? Do not make replacement loyalty adjustments. Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the Perkstar business name and affected appointment numbers so cleanup can be reviewed without exposing customer contact details or credentials. # Acuity Scheduling Source: https://developers.perkstar.co.uk/integrations/acuity/index Connect Acuity appointments to an existing Perkstar Stamp card for attendance earning and one-time online reward codes. Use Acuity Scheduling as the appointment system while Perkstar remains the loyalty system of record. Appointments sync into **Bookings**, eligible attendance credits an existing Stamp card enrolment, and configured rewards receive a one-time Acuity code for online booking. Match one existing Perkstar customer and card enrolment by email or normalised phone number. Names are never used for matching. Mark a confirmed appointment attended after its end time plus 15 minutes and apply the linked card's visit or spend rule once. Create a unique Acuity certificate for a completed-card, milestone or birthday reward and keep the code on the customer's Wallet pass. ## System boundaries | Event or responsibility | System of record | Result | | - | - | - | | Appointment schedule, service, calendar and status | Acuity | Perkstar keeps the fields required to show and reconcile the booking | | Loyalty membership, stamps, rewards and Wallet pass | Perkstar | An eligible attended appointment credits the existing enrolment once | | Coupon, package, gift or subscription value and restrictions | Acuity | Perkstar creates a unique code against the configured Acuity source | | Appointment payment and payment-processor refund | Acuity or its payment processor | Perkstar does not use payment status as an attendance gate and does not sync refunds | | Normal cancellation or no-show | Acuity | Perkstar applies the supported loyalty and certificate correction once | Acuity is an **attendance integration, not a payment-settlement integration**. A paid flag is not required for attendance earning, and an Acuity or payment-processor refund does not reverse loyalty. Record a normal cancellation or no-show in Acuity when the appointment outcome changes. ## Important boundaries * Acuity supports **Stamp cards only**. Points, Cashback and other card types are not available for this connection. * One Acuity account and one Stamp card can be linked to a Perkstar business. The same route applies across that Acuity account's calendars, staff and appointment types. * The customer must already exist in Perkstar and already be enrolled on the linked card. Acuity bookings never create a customer or a card enrolment. * Matching uses a unique case-insensitive email first, then a normalised phone number. A name alone never matches. * Visit rules use the configured stamps per visit. Spend rules use the Acuity appointment price and require matching Acuity and Perkstar currencies. Manual earning rules do not award automatically. If the same Stamp card is routed to Square, **Square owns earning**, including while that connection temporarily needs reconnection. Acuity continues to sync appointments and provide configured reward codes, but does not add a second credit. Keep that ownership stable while appointment or payment events may still be in flight; use a new card or contact support for a clean cutover. ## What you need * A Perkstar **Growth** plan or higher. * An active Acuity account with the required API access. Acuity documents **Premium or Powerhouse** for API credentials; check the authorising user's access before changing plans, as explained in [Setup](/integrations/acuity/setup). * Perkstar owner or manager access with permission to edit operations. * The Acuity account owner or a **Scheduling Administrator** to authorise the connection. Lower contributor levels can be limited to selected calendars. * One unarchived active or draft Stamp card. A draft can award stamps during a controlled test; activate it before serving customers. * Existing Perkstar customers already enrolled on that card. * The same business currency in Acuity and Perkstar if the card earns by spend. **Earning stamps only?** No Acuity coupon is needed. **Redeeming rewards during online booking?** First create the matching coupon or package in Acuity, including its value, eligible services and intended single-use limit, then link its numeric ID in Perkstar. Perkstar automatically creates each earned reward's unique customer code; it does not create the underlying discount or offer for you. Authorise the complete account, verify booking updates, link the card and test the full journey. Understand matching, attendance earning and the customer reward-code flow. Correct cancellations and no-shows, diagnose missing activity and disconnect safely. ## Data flow | Direction | Information | Purpose | | - | - | - | | Acuity → Perkstar | Account identity and currency; appointment reference, times, duration, service, calendar/staff label, price, paid indicator, cancellation/no-show state, customer name, email and phone, and whether a certificate was applied | Display and reconcile the booking, match an existing customer, calculate attendance earning and detect a managed code | | Perkstar → Acuity | One managed `appointment.changed` webhook subscription; generated certificate code, configured source ID and customer email where available | Receive appointment changes and create the customer's one-time reward code | | Perkstar → customer | Reward email where deliverable, booking link and updated Apple Wallet or Google Wallet pass | Let the customer use and track the reward | Perkstar retains only the appointment fields required for this workflow. It does not retain Acuity intake-form answers, internal appointment notes, payment card details or payment-processor transactions. Need help with a connection? Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the Perkstar business name, Acuity appointment number and approximate time. Never send an API key, access token, customer intake-form answer or full webhook payload. # Set up Acuity Source: https://developers.perkstar.co.uk/integrations/acuity/setup Authorise the complete Acuity account, verify booking updates, link an existing Stamp card and test attendance and reward codes. Complete these steps before relying on automatic attendance earning. Perkstar keeps appointment sync, attendance earning and online reward codes as separate setup stages so each can be verified safely. ## Before you connect * Use Perkstar Growth or higher. * Use an active Acuity account. Acuity documents that [its API access requirements](https://help.acuityscheduling.com/hc/en-us/articles/16676949253389-Using-custom-CSS-and-APIs). Its **Premium or Powerhouse** plans include access to API credentials. If Perkstar asks for your webhook signing key, confirm that **View credentials** is available for the authorising user before changing any subscription. OAuth authorisation and access to that credentials screen are separate checks; a Connect button alone does not confirm either one. * Sign in to Perkstar as an owner or manager who can edit operations. * Ask the Acuity owner or a **Scheduling Administrator** to authorise Perkstar. Acuity's lower contributor levels can be limited to selected calendars; see [Acuity access levels](https://help.acuityscheduling.com/hc/en-us/articles/16676924963341-Inviting-contributors-to-Acuity-Scheduling). * Confirm that you are connecting the intended Acuity account. Perkstar supports one Acuity account per business. ### Direct links to Acuity Sign in to **your own Acuity account** and check the business before making changes. These links contain no account, owner or coupon ID; Acuity opens them using your own login. Keep Perkstar open in another browser tab so you can return to finish setup. If Acuity asks you to sign in first, finish signing in and open the required link again. * [Create an appointment coupon](https://secure.acuityscheduling.com/products.php?action=editCoupon\&apptCoupon=1) * [Open your appointment coupons](https://secure.acuityscheduling.com/products.php?action=coupons\&apptCoupon=1) * [Open Acuity Integrations / API](https://secure.acuityscheduling.com/preferences.php?action=integrations) * [Acuity's illustrated coupon help](https://help.acuityscheduling.com/hc/en-us/articles/16676933307789-Creating-coupons-for-appointments-and-packages-in-Acuity-Scheduling) — public help, with no Acuity account login required. ## Prepare the Stamp card The card picker shows unarchived **active or draft Stamp cards**. Points, Cashback and other card types are not eligible. Before going live, confirm that: * test earning on a draft if useful, then activate the card before serving customers; * the customers you want to reward already exist in Perkstar and are already enrolled on this card; * an automatic visit or spend rule is configured; * Acuity and Perkstar use the same currency if the card earns by spend; and * the expected final, milestone and birthday rewards exist on the card. A manual earning rule does not credit appointments automatically. Perkstar cannot infer how many stamps a staff member intended to enter. Check whether this card is also routed to Square. If it is, Square remains the earning owner, including while its connection temporarily needs reconnection, and Acuity will not award attendance a second time. Keep the owner stable while appointment or payment events may still be in flight. Use a new card or contact support before switching an established card between providers. ## Connect and verify booking updates In Perkstar, open **Integrations → Marketplace**. On a phone, use Safari or Chrome, tap the menu button at the top right, then **Integrations → Marketplace**. Use the browser, not the Acuity admin app, for this setup. Find **Acuity Scheduling** and choose **Connect** on Overview or Setup. This opens the guided management page; choose **Continue to Acuity** to authorise. Before the first connection, Setup should show **Not started**. You do not need to register a developer application or ask Perkstar support to perform the normal connection. Sign in to the correct Acuity account as its owner or Scheduling Administrator and approve Perkstar's API access. On return, check the displayed Acuity account, timezone and currency. Acuity signs a dynamic webhook with the API key belonging to the user who authorised it. In Acuity, open **Integrations**, scroll to **API**, choose **View credentials**, and copy the API key for that same user. Paste it in Perkstar. Perkstar verifies the user ID and key with Acuity before saving it securely. Perkstar automatically maintains one catch-all `appointment.changed` webhook. Do not add a Perkstar webhook manually in Acuity. The integration should report that booking updates are connected. Select the prepared card under **Choose the programme credited after attendance** (called **Link your stamp card** in the older settings view). The selection saves automatically and is applied to open, uncredited Acuity bookings where safe. Connecting authorises account access; it does not by itself turn on attendance earning. Complete **Booking updates** and **Loyalty programme**, then run a test. The third stage, **Reward codes**, is **required for redemption during Acuity booking** and is counted separately from attendance earning. Skip it only if rewards will be redeemed in person. A cancelled or failed authorisation shows a message on the management page explaining how to continue. Changing the linked Stamp card turns Acuity reward codes off and clears the previous card's reward-source mappings. Reconfigure the online rewards step before issuing codes from the new card. ## Configure online reward codes **Complete this stage if customers should use rewards at Acuity checkout.** Customers can still earn attendance stamps with online reward codes off, but must redeem those rewards in person instead. You create the coupon or package that defines the reward in Acuity first. Perkstar does **not** create that discount or decide its value and eligible services for you. After you link it below, Perkstar automatically creates each customer's unique code when they earn the mapped reward. You do not need to create a separate coupon manually for every customer. For an appointment discount or free service, open **Appointment Types → Coupons → New Coupon for Appointments** in Acuity. Choose the discount, eligible appointment types and expiry. For a single-use reward, set the **Total number of uses...** to **1 total use**, not unlimited or once per client email. Keep the original setup code private; customers receive their own codes from Perkstar. You can do this in a mobile browser or Acuity's admin app. Alternatively, create an appointment package, gift or subscription with the intended reward entitlement. Use separate sources when completed-card, milestone or birthday rewards have different terms. Test the generated code's actual usage limits in Acuity. A unique generated code does not by itself make an unlimited-use source single-use. Under **Let customers use rewards when booking**, enable **Online Acuity reward codes** and add the business's HTTPS Acuity booking page. For every reward you want available online, choose **Coupon or discount** or **Package, gift or subscription**, then enter its numeric Acuity reward number from its edit page in **Acuity ID**, not the text of a discount code. For a coupon, copy the digits after `id=` in its browser address. On a phone, tap the address bar to see the full address. Leave a row blank when that reward should remain in-person only. Choose **Save reward setup**. If customers already have eligible unclaimed rewards, use **Create waiting codes** after the mappings are saved. The customer-facing label is **Acuity coupon code**. This is different from the numeric **Acuity ID** you copied from the coupon edit-page URL during setup. Customers enter their Acuity coupon code in **Package, gift, or coupon code** at Acuity checkout. Test an earned code against the intended service before going live; check its discount and that it cannot be used a second time. Percentage coupons can include add-ons, and a required deposit may still be payable, so confirm the booking total rather than assuming every free-service reward makes every booking free. ### What can be automated? Perkstar already automates the repeated work: creating an individual Acuity code when a mapped reward is earned and keeping the reward's redemption status in sync. The business creates and links the underlying offer once per reward type. Acuity's documented [certificate creation API](https://developers.acuityscheduling.com/reference/post-certificates) requires an existing coupon or package ID. Its public API documentation does not provide an endpoint for creating the underlying discount or package. The standard Perkstar connection therefore does not create those offers for you. Acuity explains how to [create appointment coupons](https://help.acuityscheduling.com/hc/en-us/articles/16676933307789-Creating-coupons-for-appointments-and-packages-in-Acuity-Scheduling) and how customers [use package, gift and subscription codes](https://help.acuityscheduling.com/hc/en-us/articles/29268134579085-Redeeming-package-gift-certificate-or-subscription-codes). ## Customer information Perkstar reads only the account and appointment fields required to display and reconcile bookings, match an existing customer and operate a reward code. It does not retain intake-form answers or internal appointment notes. When a reward code is created, Perkstar sends Acuity the configured source, generated code and the customer's email where available. A configured booking link can prefill the code and the customer's booking details. The business must tell customers about this provider connection and have an appropriate lawful basis for the data exchange. * [Perkstar privacy policy](https://dashboard.perkstar.co.uk/privacy) * [Integration recipients](https://dashboard.perkstar.co.uk/dpa/sub-processors) ## Test before going live Use a synthetic customer who already exists in Perkstar and is enrolled on the linked active Stamp card. 1. Book an Acuity appointment using the same email address and confirm it appears in Perkstar **Bookings**. 2. Reschedule it and confirm its service time changes without creating a duplicate booking. 3. Let a short appointment reach its end time, wait at least 15 minutes and confirm the exact visit- or spend-based stamp credit appears once. 4. Repeat with phone matching in a different display format and confirm the normalised number resolves the same enrolled customer. 5. Confirm that a name-only, unmatched or not-enrolled booking does not earn and does not create a customer or enrolment. 6. Earn one configured reward and confirm the email where deliverable, Wallet reward and one-time Acuity code. 7. Book with the code and confirm Perkstar records one redemption and removes the used code from Wallet. 8. Cancel one code booking normally and confirm the reward is restored. Mark a separate code booking as a no-show and confirm its code remains consumed. Continue with [Appointments and rewards](/integrations/acuity/appointments-rewards). # Aloha Cloud (NCR Silver) Source: https://developers.perkstar.co.uk/integrations/aloha-cloud/index Availability and next steps for Aloha Cloud (NCR Silver). **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Configure per-location Aloha Cloud access for sales polling and card routing when released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Aloha Cloud (NCR Silver). If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Clover Source: https://developers.perkstar.co.uk/integrations/clover/index Availability and next steps for Clover. **Controlled rollout.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Use the Clover app for scan-first customer identification, loyalty earning, redemption and refund recovery. Access requires explicit release approval and the required provider configuration; an eligible subscription alone does not enable it. ## What to do now Open **Perkstar → Integrations** and inspect Clover. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Connect and verify safely Source: https://developers.perkstar.co.uk/integrations/connection-checklist A short checklist for account ownership, access, the first result and recovery. ## Before connecting 1. Confirm the business account and the provider account or store. Give the connection a recognisable name where supported. 2. Read the integration's availability and requirements. A provider account and a paid Perkstar plan do not automatically grant every connector. 3. Decide who owns the connection and who will respond when it needs attention. 4. Review the requested access and keep keys and verification tokens private. ## Verify one result Use an authorised fixture or controlled test appropriate to the integration. | Connection | First useful result | | - | - | | Resend | Its signed test-delivery confirmation, followed by explicit activation | | POS or online store | One eligible sale matched to the intended customer, card and location | | Bookings | One qualifying attended appointment and the corresponding loyalty action | | Klaviyo | The expected profile and event, without accidentally starting a live email flow | | Analytics | A supported event in the correct property with required consent | | Zapier or Make | One workflow execution with the expected output in the destination | | Stripe Connect | Required onboarding completed and the correct charge/payout readiness | A connected badge proves authorisation or configuration, not that every business event succeeded. Read the reason, timestamp and relevant provider record behind a status. A missing signal is not a healthy signal. ## Duplicates and recovery For custom API writes, keep a stable source reference and follow [idempotency](/fundamentals/idempotency). Repeat the same controlled request and verify that it does not duplicate loyalty. Follow the provider-specific guide for refunds, cancellations and recovery. Do not run a bulk retry because a summary looks stale; first establish which records were accepted or completed. For webhooks, use the [receiver walkthrough](/guides/webhooks). Check the signed payload and delivery status. A redirect is not a successful receiver response. ## Hand over ownership Record the responsible business user, provider account, programme/location mapping, last verified result and recovery instructions. Store secrets in the appropriate secure system rather than in this handover. Before revoking access or disconnecting, review pending work and how late delivery reports will be reconciled. # Deliveroo Source: https://developers.perkstar.co.uk/integrations/deliveroo/index Availability and next steps for Deliveroo. **No self-service installation.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Route completed Deliveroo orders to loyalty cards using the restaurant mapping managed in Perkstar. This reference covers an existing or restricted connection. It is not an invitation to start a new connection. ## What to do now Open **Perkstar → Integrations** and inspect Deliveroo. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Dojo Source: https://developers.perkstar.co.uk/integrations/dojo/index Availability and next steps for Dojo. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Turn verified Dojo payment events into loyalty activity with customer matching and refund handling. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Dojo. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # EPOS Now Source: https://developers.perkstar.co.uk/integrations/epos-now/index Availability and next steps for EPOS Now. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Configure EPOS Now credentials for sales polling and customer matching when the connector is released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect EPOS Now. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Google Analytics 4 Source: https://developers.perkstar.co.uk/integrations/ga4/index Configure Google Analytics 4 measurement for supported customer journeys. Send supported customer journey events to your business's Google Analytics 4 account. This is measurement, not a loyalty balance source or proof that a message was delivered. ## Configure the connection 1. Select the intended business in **Perkstar → Integrations → Google Analytics 4 → Connect**. 2. Enter the **Measurement ID** and **Measurement API secret** from the property or data source you control in Google Analytics. 3. Save in the integration workspace. These are business-level settings inherited by its cards; do not paste a different business's credentials into a card. 4. A saved-secret hint means the secret is already stored. Leaving it untouched preserves it; entering a replacement deliberately updates it. ## Check an event Use a controlled test customer and a supported enrolment or loyalty journey with the required recorded marketing consent. Inspect the matching event in Google Analytics. The implementation requires both the identifier and secret, plus the applicable consent, before firing these events. A saved identifier alone is not a completed verification. ## Troubleshooting and ownership Check the correct business, identifier, saved secret and test customer's consent. Provider reporting can differ from Perkstar transaction totals; attribution events are not the accounting record. Do not remove consent requirements to make a test appear. Keep secrets private and rotate them through the provider when necessary. Use the available workspace controls to remove the configuration when retiring it, then confirm with a controlled test that no new event is generated. See [security and privacy](/fundamentals/security-privacy). # Google Calendar Source: https://developers.perkstar.co.uk/integrations/google-cal/index Availability and next steps for Google Calendar. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Bring calendar appointments into the loyalty workflow when the connector is released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Google Calendar. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Find your integration Source: https://developers.perkstar.co.uk/integrations/index Choose a connection, check availability and follow the correct setup guide. Connect an existing business tool, send customer invitations from your own email account, or build with the API. Start with the job you need to do. Connect, test and activate your own sending account. Confirm access, ownership, one result and recovery. Start with a scoped test key and a small request. ## Find your provider **Available** means a connection is offered subject to the business's permissions, plan and provider configuration. **Beta / controlled rollout** may require explicit access. A listing here does not enable a provider that the dashboard marks unavailable. Availability reviewed **13 September 2026**. ### Email and marketing | Integration | Availability | What the guide helps with | | - | - | - | | [Resend](/integrations/resend) | Available | Send invitations and card install links through your own email account. | | [Klaviyo](/integrations/klaviyo) | Available | Sync customer profiles, loyalty properties and lifecycle events into Klaviyo segments and flows. | | [Mailchimp](/integrations/mailchimp) | Beta | Sync consenting loyalty customers and their current balances, tiers, birthdays and activity into a Mailchimp audience. | ### Point of sale | Integration | Availability | What the guide helps with | | - | - | - | | [Loyverse](/integrations/loyverse) | Beta | Scan Wallet QR codes, earn points from paid receipts and spend a Perkstar points-to-cash balance at the till. | | [Square](/integrations/square) | Beta / controlled rollout | Earn loyalty from customer-attributed Square payments with refund reconciliation and location routing. | | [SumUp POS (Custom Loyalty)](/integrations/sumup-pos) | Beta / controlled rollout | Use SumUp POS Custom Loyalty for Wallet QR lookup, loyalty rewards and replay-safe completed-sale settlement. | | [Clover](/integrations/clover) | Beta / controlled rollout | Use the Clover app for scan-first customer identification, loyalty earning, redemption and refund recovery. | | [Lightspeed Restaurant K-Series](/integrations/lightspeed-k-series) | Beta / controlled rollout | Reconcile eligible closed restaurant sales and refunds for existing Perkstar members. | | [Lightspeed Retail](/integrations/lightspeed) | Not open for new connections | Connect Lightspeed Retail sales and customer activity when the integration is released. | | [Aloha Cloud (NCR Silver)](/integrations/aloha-cloud) | Not open for new connections | Configure per-location Aloha Cloud access for sales polling and card routing when released. | | [EPOS Now](/integrations/epos-now) | Not open for new connections | Configure EPOS Now credentials for sales polling and customer matching when the connector is released. | | [GoDaddy Poynt](/integrations/poynt) | Not open for new connections | Configure a Poynt business for sales polling and customer matching when released. | | [MX POS](/integrations/mx-pos) | Not open for new connections | Configure MX POS transaction polling and card routing when the connector is released. | | [Dojo](/integrations/dojo) | Not open for new connections | Turn verified Dojo payment events into loyalty activity with customer matching and refund handling. | | [Toast](/integrations/toast) | Existing / restricted connections | Connect Toast sales and customer activity when the production integration is released. | | [Access EPoS](/integrations/access) | Existing / restricted connections | Connect Access hospitality locations when provider access and the production integration are released. | | [Sunmi](/integrations/sunmi) | Existing / restricted connections | Connect Sunmi Cloud locations for sales polling when the production connector is released. | | [PAX](/integrations/pax) | Unavailable | PAXSTORE manages terminal fleets but does not provide the transaction feed Perkstar requires. | Square credits customer-attributed sales and reverses refunds. Unmatched Square contacts are not retained. Rewards redeem through the Perkstar pass and scanner; Square Loyalty is not required or written. See the [Square guide](/integrations/square) for the production beta’s access and data-use requirements. ### Online stores and payments | Integration | Availability | What the guide helps with | | - | - | - | | [Shopify](/integrations/shopify) | Beta | Reward online and POS orders with customer matching, refund recovery, catalogue sync and location routing. | | [Stripe Connect](/integrations/stripe) | Available | Connect Stripe to receive customer payments and manage payout readiness from Perkstar. | ### Bookings and delivery | Integration | Availability | What the guide helps with | | - | - | - | | [Acuity Scheduling](/integrations/acuity) | Available | Reward attended appointments, handle no-shows safely and configure booking redemption codes. | | [Google Calendar](/integrations/google-cal) | Not open for new connections | Bring calendar appointments into the loyalty workflow when the connector is released. | | [Setmore](/integrations/setmore) | Not open for new connections | Sync appointments and credit the customer's wallet after attendance. | | [Mindbody](/integrations/mindbody) | Not open for new connections | Connect a studio to reward eligible class and appointment attendance. | | [Deliveroo](/integrations/deliveroo) | Existing / restricted connections | Route completed Deliveroo orders to loyalty cards using the restaurant mapping managed in Perkstar. | ### Analytics | Integration | Availability | What the guide helps with | | - | - | - | | [Google Analytics 4](/integrations/ga4) | Available | Send supported customer journey events to the business's GA4 property. | | [Meta Pixel](/integrations/meta-pixel) | Available | Measure supported sign-up and loyalty activity in Meta without exposing customer secrets. | | [TikTok Pixel](/integrations/tiktok-pixel) | Available | Measure supported sign-up and loyalty activity in TikTok Ads Manager. | ### Automation | Integration | Availability | What the guide helps with | | - | - | - | | [Zapier](/integrations/zapier) | Public beta | Use Perkstar triggers and actions in Zapier to connect loyalty activity with other business tools. | | [Make](/integrations/make) | Private beta | Build visual loyalty automations with Make modules and webhooks when the public connector is released. | ## Build without a native connector Use the [POS walkthrough](/guides/pos), [customer sync guide](/guides/customer-sync), [webhook guide](/guides/webhooks) or [marketplace OAuth guide](/guides/oauth-marketplace). Check the [API availability matrix](/support/api-availability) before promising a workflow: a native integration capability does not imply an equivalent public API. # Klaviyo Source: https://developers.perkstar.co.uk/integrations/klaviyo/index Connect loyalty profiles and events to Klaviyo and verify the correct account. Use Perkstar loyalty data in Klaviyo segments and flows. This sync connection is separate from [Resend email delivery](/integrations/resend): it does not change the account Perkstar uses to send invitation emails. ## Connect 1. Sign in to the intended business with permission to manage integrations. 2. Open **Integrations → Klaviyo → Connect** and review the provider authorisation. 3. Choose the intended Klaviyo account and return to the same Perkstar business. 4. Open **Manage** and confirm the connected account name. Check for any setup or data-delivery warning before relying on the connection. Availability depends on the business's access and platform configuration. Do not create a second active connection to work around an account mismatch. ## Verify the first result Use an authorised test customer and one supported loyalty action. Compare the customer's profile properties and corresponding event in Klaviyo with Perkstar's **Last successful sync**, **Queued events**, **Failed events** and recent delivery rows. A successful authorisation is not proof that a flow sent an email. The synchronised data includes customer identity/contact details, cards, balances, reward activity, join and activity dates, group/birthday and recorded email/SMS consent properties. Configure your Klaviyo flows to respect those choices. Keep emails disabled in a test flow unless a controlled test send is intended. ## Recover and disconnect Inspect failed events and the visible error first. Repair an expired authorisation through the workspace; do not import the same audience repeatedly to force a retry. Disconnect through **Manage** when retiring the connection and review any separately scheduled Klaviyo flows in Klaviyo. Disconnecting does not recall mail already accepted by that provider. Contact support with the account and event reference, without customer lists or credentials. # Lightspeed Restaurant K-Series Source: https://developers.perkstar.co.uk/integrations/lightspeed-k-series/index Availability and next steps for Lightspeed Restaurant K-Series. **Controlled rollout.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Reconcile eligible closed restaurant sales and refunds for existing Perkstar members. Access requires explicit release approval and the required provider configuration; an eligible subscription alone does not enable it. ## What to do now Open **Perkstar → Integrations** and inspect Lightspeed Restaurant K-Series. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Lightspeed Retail Source: https://developers.perkstar.co.uk/integrations/lightspeed/index Availability and next steps for Lightspeed Retail. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Connect Lightspeed Retail sales and customer activity when the integration is released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Lightspeed Retail. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Use Loyverse at checkout Source: https://developers.perkstar.co.uk/integrations/loyverse/checkout Show staff how to scan a customer's Wallet card, award points and redeem an exact balance through Loyverse POS. Staff stay inside the Loyverse POS journey. The customer only needs the branded loyalty card in Apple Wallet or Google Wallet. ## Find the customer and earn points Add the sale items in Loyverse as normal. Tap **Add client** or **Add customer** and scan the QR code on the customer's Perkstar Wallet card with the device camera or compatible barcode scanner. Check the correct profile has opened, then tap **Add to ticket**. Take payment in Loyverse normally. Perkstar applies the connected card's automatic earning rule after it receives the paid receipt. Attach the customer before payment. Perkstar does not guess who made an unattached purchase and will not award that sale to someone later. ## Redeem some or all of the balance Add the items, scan the Wallet card and add the matched profile to the ticket. Open the customer profile and tap **Redeem points**. Use the full maximum or enter a lower eligible amount requested by the customer, then tap **OK**. Check the point discount under **Discounts**, then tap **Charge** and complete payment. Loyverse labels the checkout value as points, but while this integration is live it represents spendable money. At a GBP till, **5.00 means £5.00**. Perkstar reads the exact monetary discount from the paid receipt, so entering £1.25 deducts £1.25—not £0.01 and not the whole available balance. The customer can spend only the balance currently available. Before the configured minimum is reached, the spendable balance is zero and the Wallet card shows the points remaining until it unlocks. ## What the customer experiences 1. Join the business's Points card and add it to Apple Wallet or Google Wallet. 2. Show the Wallet QR code at checkout. 3. Earn points after a paid sale when the customer was attached to the ticket. 4. Once the minimum is reached, choose how much available balance to spend. 5. See updated Points and Balance fields after Perkstar reconciles the receipt and the Wallet refresh completes. ## When updates appear Online receipts normally begin syncing when Loyverse sends a receipt update. If that notification is delayed, Perkstar's five-minute recovery sync looks for the missing change. The Wallet refresh is queued after the loyalty update and its display timing can also depend on the Wallet platform and phone connection. If a POS device takes a sale offline, Perkstar cannot see it until Loyverse syncs the receipt. Reconnect the device and allow the normal sync to finish. Do not repeat the sale or make a manual loyalty adjustment to compensate for a delay. Loyverse provides illustrated instructions for [scanning a customer barcode](https://help.loyverse.com/help/scanning-customer-barcode) and [redeeming points](https://help.loyverse.com/help/points-discounts). # Move customers and send invitations Source: https://developers.perkstar.co.uk/integrations/loyverse/customer-migration-invitations Copy existing Loyverse customers and points safely, choose whether to add welcome points, and invite each customer to install the right Wallet card. Perkstar can move the existing Loyverse customer directory and current points without asking the business to prepare and upload a separate spreadsheet. Nothing is sent to customers automatically: the business reviews the completed copy first, then chooses email, paid SMS or both. Customer records, exact Loyverse customer IDs and current points become the opening Perkstar membership and balance. Keep imported balances only, or add the card's configured welcome points to eligible migrated customers. Invite customers using the included service email, paid SMS after the plan is active, or both. ## Before starting the copy In **Loyverse Back Office → Settings → Loyalty**, save the earning percentage as **0%**. From the Step 2 snapshot until activation finishes, staff must not redeem old Loyverse points or manually edit customer point balances. Finalise the Perkstar card's earning, conversion and expiry rules first. The copy preserves the current Loyverse points; it does not recalculate historical purchases or infer a different cash value from the old receipt history. ## Review and copy the customers In Perkstar's Loyverse setup, choose **Check existing Loyverse customers**. Perkstar shows the source count, customers safe to copy, total opening points and a short identifying list for any duplicate contacts, invalid balances or existing customer codes that need attention. **Keep imported balances only** is selected by default. Alternatively, the business owner can choose to add the selected card's configured welcome points once to each eligible migrated membership. Before approval, Perkstar shows the points per customer, maximum eligible recipients, maximum additional points, cash-equivalent exposure and the configured expiry. Customers whose welcome decision was already processed are skipped, so the same membership does not receive it twice. Failed and excluded rows receive nothing extra. Confirm that the business controls the data and is instructing Perkstar to perform this service migration. This does not grant marketing consent. If existing Loyverse customer codes are shown, expressly approve their later replacement with the managed Wallet QR identifiers. Choose **Copy customers and points**. Perkstar binds each row to the exact Loyverse customer ID and copies `total_points` as the opening Perkstar points balance. The work continues safely in the background, and failed rows can be reviewed and retried without duplicating successful balances or welcome points. The saved card and welcome-points choice are locked for this migration. A retry, interrupted connection or reconnect cannot silently switch the remaining customers to a different card or policy. Do not continue to scanning or send invitations while Step 2 shows excluded, errored or incomplete customers. The setup remains closed until the current cohort is complete so no customer is invited to a membership that is not ready. ## Invite customers to install the card When Step 2 says **Customer migration complete**, open the import results. The business can use either channel or both: | Channel | Availability | What happens | | - | - | - | | Included service email | Available for the completed migration, including during an eligible trial | Sends the ready-made transition message and secure personal install link. It does not consume SMS credits or opt the customer into marketing. | | Paid SMS | Available after the Perkstar subscription is active and enough SMS credits are available | Shows the exact eligible audience, segments and credit cost before the business confirms the one-time send. | Perkstar skips customers who have already installed the Wallet card before the final provider send. Suppressed, opted-out or otherwise ineligible contacts are not sent through the relevant channel. Starting invitations freezes replacement of that completed migration; contact Perkstar if a later source correction is required. For a first rollout, use **Send one test invitation** before releasing the full audience. Enter the saved email address or mobile number for one eligible migrated membership, then review the exact message, recipient and channel. Email is included; a test SMS needs an active paid plan and the displayed SMS credit. The test uses the same signed membership link and provider-boundary checks as its full channel, but it does not consume or close either remaining audience. After that person installs the Wallet card, Perkstar excludes them from the later install-invitation audience. A test invitation is a real customer message, not a preview sent to an arbitrary address. Send it only to a customer or owner-controlled test membership that the business is authorised to contact. Once the test link is released, Perkstar locks that completed migration against replacement so the link cannot be redirected to a different import. Perkstar never sends the migration invitation automatically. The business reviews the result, message and audience, then chooses when to send. ## What the customer receives Every invitation contains a signed link for one exact migrated membership. It does not ask Perkstar to find a balance by name or create a second account. * An email or mobile number already saved in Loyverse is shown read-only so the customer cannot accidentally detach the Wallet card from the preserved membership and points. * If one contact method was missing, the customer can add it to the same membership before installing the card. * The customer adds the business's branded card to Apple Wallet or Google Wallet and shows its QR code at checkout. * If welcome points were approved and the customer was eligible, the invitation explains that they were added in addition to the copied opening balance. ## Continue the integration 1. Send one email or paid-SMS test invitation to an owner-controlled migrated membership and install its Wallet card. 2. Enable **customer card scanning** and wait for **X of Y customers ready**. 3. Resolve every listed customer-code or profile conflict. 4. Test the installed Wallet QR on every POS device using its camera or compatible 2D scanner. 5. Enable till redemption and wait for the two balance checks and required 15-minute safety period to finish. 6. After the till test passes, review and release the remaining email, paid SMS or both. Perkstar never sends the broad audience automatically. For approximately 550 customers, till activation normally takes 30–90 minutes, depending on Loyverse response time. The page can be closed after activation starts; Perkstar continues from durable checkpoints. Do not serve customers through the integration until scanning, earning and redemption all report as connected. Continue with [Use Loyverse at checkout](/integrations/loyverse/checkout). # Loyverse POS Source: https://developers.perkstar.co.uk/integrations/loyverse/index Connect Perkstar to Loyverse for Wallet QR scanning, automatic points, exact balance redemption and matched refunds. Loyverse Run one complete loyalty journey at the Loyverse till. Staff scan the QR code on a customer's branded Apple Wallet or Google Wallet card, paid purchases earn points automatically, and the customer can spend all or part of their available Points-to-Cash balance during checkout. Scan the customer's Wallet QR code and attach the matching Loyverse customer to the ticket. Perkstar reads the paid Loyverse receipt and applies the earning rules on the connected Points card. Redeem the full available balance or enter a smaller amount without leaving Loyverse POS. **Set Loyverse's own loyalty earning percentage to 0% before enabling till redemption.** Perkstar calculates points from the paid receipt. Leaving both systems earning can reward the same purchase twice. ## What stays in sync | Event | What Perkstar does | | - | - | | Customer scans their Wallet card | Finds or creates the eligible Loyverse customer and links the Wallet QR identifier | | Paid sale | Applies the connected card's earning rule once | | Partial or full redemption | Deducts the exact monetary point discount recorded on the paid receipt | | Eligible refund or cancellation | Reverses applicable earning and restores supported redeemed value once | | Loyalty balance changes | Refreshes the Wallet card and the spendable value available in Loyverse | During initial setup, Perkstar also provides a controlled migration that copies the existing Loyverse customer directory and each customer's current points as their opening Perkstar balance. It binds migrated members to their exact Loyverse customer IDs rather than trying to reconstruct old receipt history. Perkstar is the source of truth for points, spendable balances and loyalty activity. Loyverse remains the source of truth for sales and refunds. ## What you need * A Perkstar business and plan that includes the Loyverse integration. * Owner or manager access in Perkstar and permission to connect apps in the intended Loyverse business. * The same two-decimal currency in both systems. * An active individual **Points card** with automatic earning, a QR code and flexible Points-to-Cash spending. * An online Loyverse POS device with camera barcode scanning enabled, or a compatible external barcode scanner. Prepare the card, set Loyverse to 0%, connect and activate safely. Preserve current points, choose whether to add welcome points and invite customers by included email or paid SMS. Give staff a clear scan, earn and partial-redemption workflow. Handle corrections, delayed updates, troubleshooting and disconnection. ## Data flow | Direction | Information | Purpose | | - | - | - | | Loyverse → Perkstar | During initial migration: customer directory, exact customer IDs, contact details, customer code and current points; during normal use: business identity, currency, customer reference, and paid receipt or refund information | Preserve existing members and opening points, match the correct customer, calculate earning, read the exact redemption and reconcile corrections | | Perkstar → Loyverse | Customer name, email and optional phone when a profile must be created; managed Wallet QR identifier; current spendable balance | Find the customer by scanning and make their balance available through **Redeem points** | | Perkstar → Wallet platforms | Updated Points, Balance and programme fields | Keep the customer's Apple Wallet or Google Wallet card current | Products, inventory, employees, taxes and payment information are not synchronised. Perkstar connects through Loyverse OAuth, so the business does not share its Loyverse password with Perkstar. Need help with a live connection? Email [Loyverse@perkstar.co.uk](mailto:Loyverse@perkstar.co.uk) with the Perkstar business name, Loyverse receipt number and approximate time. Never send a password, access token or customer's Wallet QR value. # Refunds and troubleshooting Source: https://developers.perkstar.co.uk/integrations/loyverse/refunds-troubleshooting Reconcile Loyverse refunds, diagnose delayed loyalty updates and disconnect the integration safely. ## Refunds and cancellations Process a refund or cancellation against the **original Loyverse receipt**. Perkstar reverses the applicable earning and restores redemption value supported by that correction. A cancellation is treated as a full correction, and the same update is safe to receive more than once. A refund against a sale created before the Step 2 migration snapshot does not automatically adjust Perkstar points. Historical purchases were represented by the copied opening balance rather than separate Perkstar receipt credits, so Perkstar does not reconstruct and then reverse an old sale. Contact [Loyverse@perkstar.co.uk](mailto:Loyverse@perkstar.co.uk) if the business needs an opening-balance correction for that historical refund. If Perkstar cannot safely match the correction to its original sale or determine the supported amount, it does not invent a points or money adjustment. Only the affected customer's published balance is held at zero and a review issue appears on the Loyverse integration page while other receipts continue syncing. Do not make a manual points or balance adjustment when a refund needs review. Record the customer, original receipt number and time, then contact [Loyverse@perkstar.co.uk](mailto:Loyverse@perkstar.co.uk). ## Troubleshooting Do not enable scanning or send invitations yet. Open the migration result, use the identifying issue list to correct duplicate contact details, invalid balances or customer-code conflicts in Loyverse, then run the guided refresh or retry. Perkstar keeps successful rows and their points safe; a retry does not grant the opening balance or approved welcome points twice. If invitations have already started, contact support before changing the source cohort. Invitations open only for the exact current migration after every eligible customer has copied successfully. The included service email can be used during an eligible trial. Paid SMS requires an active paid subscription and enough SMS credits; its preview shows the eligible audience, message segments and credit cost. Customers without a usable contact method cannot be invited remotely and need a staff-assisted handoff. Use its **Edit** link under **Needs changes**. Confirm it is an active individual Points card, earns automatically, uses flexible Points-to-Cash with a positive minimum, displays a QR code and requires First name and Email. Save the guided changes and return to Loyverse setup. Confirm customer scanning is on, the customer joined the selected card, and the device camera or external scanner is enabled. Check the integration page for duplicate-email, customer-code or missing-details issues, correct the record and choose **Retry customer sync**. Confirm the correct customer was attached before payment, the connected card is active, the receipt is paid and the POS is online. Check connection status and the last recovery sync before retrying. Perkstar does not guess the customer for an unattached receipt. Flexible Points-to-Cash remains locked until the configured minimum is reached. The Wallet card shows the points still needed. Also confirm till redemption has finished activating. Immediately open **Loyverse Back Office → Settings → Loyalty**, save **0%** and leave it there. Do not manually edit Loyverse points while Perkstar till redemption is active. Record the receipt and contact Perkstar support. Keep the POS online and allow the receipt to sync. Perkstar uses real-time receipt notifications with a five-minute recovery path, and the Wallet display can update shortly after the loyalty ledger. Check the dashboard before repeating an action. Stop redemption and reconnect the same Loyverse business only after checking its balances and managed customer codes. If Loyverse access was revoked first, manually clear any remaining Perkstar-published values before turning redemption back on. Perkstar stopped instead of guessing about a changed or uncertain Loyverse balance. During the first cutover, turn off customer card scanning, wait for every managed code to be restored, then run the safe recovery check in Step 2\. If that check says the value cannot be verified, do not edit it; contact Perkstar support. During a later reactivation, review the unexpected old Loyverse points balance. Retry activation only after you have confirmed it is safe to return that old Loyverse balance to zero; contact support if the value may be genuine. ## Frequently asked questions No. Loyverse requires the complete scan, automatic earn and flexible monetary redemption journey, so only compatible Points cards are available. Yes. Once the card's minimum has unlocked spending, staff can enter any eligible amount up to the available balance and ticket limit. Perkstar deducts the exact monetary point discount on the paid receipt. No. Products, inventory, employees, taxes and payment information are not synchronised. The integration exchanges only the business, customer, receipt, refund, QR identifier and balance information required for loyalty. ## Disconnect safely Disconnect inside Perkstar first. Perkstar needs working Loyverse access to release its scan identifiers, reconcile outstanding receipts and clear the balance values it published. Open **Perkstar → Settings → Integrations → Loyverse**, choose **Turn off card scanning** and wait until the managed customer scan codes are released. Choose **Disconnect Loyverse**. Perkstar keeps receipt reconciliation active while it clears and verifies published balances. Resolve any displayed refund review first. Keep Loyverse authorised while clearing and verification finish. Only after Perkstar reports **Disconnected** should you remove the app from Loyverse Back Office. Disconnecting does not delete ordinary Loyverse customer profiles or the business's own Perkstar cardholders. Perkstar deletes the Loyverse credentials and locally held API-derived copies after disconnection, while retaining the de-identified Perkstar loyalty and accounting ledger under its normal retention rules. Already revoked Perkstar from Loyverse? Manually clear any remaining Perkstar-published points and managed customer codes before using Loyverse loyalty again, then contact [Perkstar support](mailto:Loyverse@perkstar.co.uk) for guidance. # Set up Loyverse Source: https://developers.perkstar.co.uk/integrations/loyverse/setup Prepare a compatible Points card, set Loyverse earning to 0%, connect the businesses and test the complete journey. Complete every step before serving customers. Perkstar keeps earning and till redemption off until the required card, scanning and balance checks are ready. ## Before you connect * Confirm Perkstar and Loyverse use the same currency. Till redemption requires a currency with two decimal places. * Sign in as a Perkstar owner or manager and use a plan that includes Loyverse. * Make sure you can approve apps for the intended Loyverse business. * Finalise the connected Points card's earning and Points-to-Cash rules before moving customers. Perkstar copies the current Loyverse points balance; it does not rebuild value from receipt history. * Keep every POS device online while configuring and testing it. Perkstar will not clear an existing Loyverse points balance until its direct migration has recorded every eligible customer and copied the current points exactly. Activation then validates the same snapshot, clears the old balances twice and publishes only each customer's spendable Perkstar balance. ## Prepare the Points card The card picker shows eligible cards under **Ready to connect**. Cards under **Needs changes** cannot be selected and include an **Edit** link explaining what to fix. A compatible card must be: * active and unarchived; * a Points card for individual customers, not a group-enrolment card; * configured to earn automatically by spend or visit, rather than by manual points entry; * configured with an ongoing Points-to-Cash balance and a valid conversion; * set to flexible spending with a positive minimum balance before spending; * configured to display a QR code; and * configured to require **First name** and **Email** on the sign-up form. Stamp cards, reward-level Points cards, set-amount Points-to-Cash cards, group-enrolment cards and manual-earning cards cannot be connected. Flexible Points-to-Cash is required because a cashier can enter any eligible amount up to the available balance. ## Set Loyverse earning to 0% Sign in to the same Loyverse business you will connect to Perkstar. Go to **Settings → Loyalty**. Set the loyalty earning percentage to **0%**, then select **Save**. This setting applies across the Loyverse account. Perkstar cannot read or change it through the Loyverse API, so you must confirm it during activation and leave it at 0% while the integration is live. See [Loyverse's loyalty instructions](https://help.loyverse.com/help/how-customer-loyalty-program). ## Connect and activate [Start the Loyverse connection](https://dashboard.perkstar.co.uk/install/loyverse), sign in to Perkstar and choose the business if asked. Authorise access to Loyverse business details, customers and receipts. On return, check the Loyverse business name and currency before continuing. Select the intended card under **Ready to connect**, then choose **Use this card with Loyverse**. Use the guided **Edit** link if a card is under **Needs changes**. In **Step 2**, choose **Check existing Loyverse customers**. Review the customer count, total points and any named issues. The owner can keep the copied balances exactly as they are—the default—or approve the card's configured welcome points for eligible existing customers. Perkstar shows the maximum points and cash-equivalent exposure before anything starts. Confirm the data-transfer instruction and, where shown, approve replacing the exact existing customer codes. Then choose **Copy customers and points**. Perkstar copies `total_points` as the opening membership balance; it does not recalculate old purchases. Follow the [customer migration and invitation guide](/integrations/loyverse/customer-migration-invitations) for the full transition journey. Only after Step 2 says the migration is complete, open its results. For the first rollout, send one controlled included-email or paid-SMS test to an eligible owner-controlled membership, then complete the till checks below before releasing the remaining included service email, paid SMS, or both. Perkstar does not message customers automatically. Every message opens the exact migrated membership so the preserved balance stays attached to the right person. Read and confirm the customer data-sharing notice, then choose **Enable customer card scanning**. Customers moved in Step 2 remain bound to their exact Loyverse profiles. Perkstar publishes each managed Wallet QR identifier and shows live progress as **X of Y customers ready**. Resolve every listed conflict before till redemption is available. For customers who join after cutover, Perkstar links one unambiguous exact-email profile or creates an eligible profile when none exists. In Loyverse POS, open **Settings → General** and enable **Use camera to scan barcodes**, unless the device uses a compatible external scanner. Tap **Add customer**, scan a test Wallet card and confirm the correct customer opens. Repeat this on every new or replacement device. On a Teya Android terminal running Loyverse, try the built-in camera first. A SUNMI Blink or another compatible 2D scanner can be used in USB HID/keyboard mode when the terminal or dock provides USB host/OTG access. Test the exact terminal, dock and scanner together before buying or rolling out hardware. Confirm separately that every device can scan, Loyverse is set to 0%, and existing balances may be replaced. Choose **Enable till redemption** and allow about 20 minutes for a small customer list. A list of around 550 customers typically takes 30–90 minutes; lists above 2,000 can take several hours. Activation includes a required 15-minute safety wait between two complete balance checks. You can leave the page after starting because Perkstar continues safely in the background. Keep Loyverse earning at 0% and do not let staff redeem or manually edit old Loyverse points from the Step 2 snapshot until activation finishes. Do not serve customers until the page says scanning, earning and redemption are connected. ## Customer information used for scanning During the one-time transition, Perkstar reads the existing Loyverse customer directory, exact customer IDs, contact details, current points balances and customer codes so the business can preserve its loyalty members and value. When scanning is enabled, Perkstar sends the customer's name, email address, optional phone number and managed Wallet scan identifier to Loyverse. Customer reference IDs, receipts, redemptions and balance data are exchanged to run the integration. The business must instruct this transfer, tell customers about the sharing and have an appropriate lawful basis. No marketing consent is inferred. * [Perkstar privacy policy](https://dashboard.perkstar.co.uk/privacy) * [Integration recipients](https://dashboard.perkstar.co.uk/dpa/sub-processors) ## Test before going live Use a synthetic customer and record the expected result for the connected card's exact earning and conversion rules. 1. Scan the Wallet card through **Add customer**, attach the customer and complete one paid sale without redemption. 2. Confirm points were added once and the Wallet fields updated. 3. Complete another sale and redeem a smaller amount, such as £1.25 from a larger available balance. 4. Confirm precisely that amount was deducted—not pennies and not the complete balance. 5. Refund the second sale against its original receipt and confirm the eligible correction was applied once. If setup stops or a button remains unavailable, follow the on-screen **Before you can continue** list. The Loyverse page can also send a redacted setup snapshot to Perkstar support and returns a reference number. That snapshot contains milestones, permission state and aggregate counts only—not customer contact details, individual balances, access tokens or raw provider responses. Continue with the [staff checkout guide](/integrations/loyverse/checkout). # Mailchimp Source: https://developers.perkstar.co.uk/integrations/mailchimp/index Connect a Mailchimp audience and use consenting customers' loyalty data in segments and automations. Use Perkstar loyalty data to build Mailchimp segments and automations, such as birthday offers, VIP rewards and reminders for customers who have not visited recently. You create the emails and automations in Mailchimp. This integration is in beta on Growth and Scale plans. Availability in your dashboard depends on deployment and your business's access. Verify the first result in a dedicated test audience before relying on it for customer campaigns. ## Connect your audience 1. Sign in to the intended Perkstar business with permission to manage integrations. 2. Open **Integrations → Mailchimp → Connect**. 3. [Create a dedicated Mailchimp API key](https://mailchimp.com/help/about-api-keys/) and paste it into the connection form. Perkstar encrypts the key and does not display it after saving. Do not send it to support or paste it into a chat. 4. Load your audiences and select the one that should receive loyalty customers. 5. Review any automations already running for that audience, then enable sync. Adding or updating contacts can trigger those automations. Start with a dedicated test audience when verifying the connection. Perkstar adds nine audience fields for its loyalty data. It leaves unrelated fields alone. If a Perkstar field already exists with an incompatible type, the setup screen explains which field needs attention. One Mailchimp account and one audience can be linked to each business. Contact support to change either after setup so existing unsubscribe history is preserved. ## What syncs Customers need a valid email address, current email-marketing consent and a loyalty enrollment. Customers without consent, deleted or anonymized customers and test pass addresses are excluded. | Audience field | Value | | - | - | | Email | Customer email address | | `PSFIRST` / `PSLAST` | First and last name | | `PSPOINTS` | Total points balance across active points cards | | `PSSTAMPS` | Total stamp balance across active stamp cards | | `PSREDEEM` | Rewards redeemed across active enrollments | | `PSCARDS` | Active card names | | `PSTIER` | Current loyalty and membership tiers | | `PSACTIVE` | Latest activity date across active enrollments | | `PSBDAY` | Birthday month and day, without the year | Existing eligible customers sync in batches. Customer and enrollment changes are queued automatically; the background worker runs every minute. **Sync now** processes a batch immediately when the connection is ready, with any remainder continuing in the background. Card and tier configuration changes are reconciled daily. Large audiences or provider retries can take longer. Use these fields in Mailchimp to select customers and configure automations. Perkstar does not create campaigns or send a history of individual loyalty events through this connection. Phone numbers, addresses, notes and wallet links are not exported. ## Check consent and the first result Use a consenting test customer with a loyalty enrollment. Enable sync and compare their audience fields in Mailchimp with their Perkstar profile. Change their points balance and verify the next update. Confirm that a non-consenting test customer is absent. Connection success alone does not mean an email was delivered. An existing Mailchimp unsubscribe remains in effect when loyalty data changes. Perkstar never automatically resubscribes an existing member. New contacts follow the audience's double opt-in setting; Mailchimp may send a confirmation email and keep them pending until they confirm. Withdrawing consent in Perkstar, anonymizing or deleting a linked customer queues an unsubscribe in Mailchimp. Changing email unsubscribes the former address before syncing the new one. Mailchimp opt-outs do not change the customer's other Perkstar messaging preferences. ## Recover, pause or disconnect Open **Manage** to review the connected account, audience, sync counts and recent issues. Temporary failures retry automatically. Reconnect with an active API key if Mailchimp rejects the stored key. Resolve duplicate customer emails in Perkstar before retrying those customers. Pausing or disconnecting stops future sync calls, including consent withdrawals. It leaves existing Mailchimp contacts and automations in place, so manage those in Mailchimp as needed. A request already in progress may finish. Disconnect clears the key held by Perkstar; revoke the dedicated key separately in Mailchimp if it is no longer needed. Reconnect to the same account and audience to resume. # Make data and security Source: https://developers.perkstar.co.uk/integrations/make/data-security Understand OAuth scopes, personal-data flow, consent, Make retention surfaces, and shared responsibilities. Perkstar for Make uses OAuth with tenant-scoped access. The person connecting the app approves one Perkstar business; the resulting Make connection cannot read or write another business. Do not share a raw Perkstar API key with a scenario builder, contractor, or destination app. ## OAuth permissions The private-beta Make OAuth client requests these eight baseline scopes for the guided modules: | Scope | Why the app needs it | | - | - | | `CUSTOMERS_READ` | Find customers and return current customer fields needed by searches and guided workflows. | | `CUSTOMERS_WRITE` | Create or update customers through the explicit guided actions. | | `ENROLLMENTS_READ` | Find a customer/card relationship, balance, status, and available Wallet links. | | `CARDS_READ` | Populate dynamic Card selectors and validate card-aware modules. | | `EVENTS_READ` | Read bounded recent event samples where the trigger setup requires them. | | `WEBHOOKS_WRITE` | Create/delete app-owned subscriptions and attest signed deliveries behind attached Make webhooks. | | `MARKETPLACE` | Enrol customers, record supported loyalty activity, and reverse eligible marketplace transactions. | | `PUSHES_WRITE` | Send one consent-checked Wallet push through the explicit action. | The registered client also permits five **optional advanced scopes**. They are not granted silently: the person creating the Make connection must explicitly request the required advanced scope and approve it on Perkstar's consent screen. | Optional scope | Advanced public API use | | - | - | | `ENROLLMENTS_WRITE` | Call a documented public enrolment mutation without a guided module. | | `TRANSACTIONS_READ` | Read a supported transaction resource through **Make an API Call**. | | `TRANSACTIONS_WRITE` | Call a supported direct transaction write after designing retry protection. | | `WEBHOOKS_READ` | Read supported app-owned webhook resources through the public API. | | `LOCATIONS_READ` | Read the connected business's supported location resources. | Granting all 13 allowed scopes is not required for ordinary guided scenarios. Choose only the optional access required by the documented universal call. To add an advanced scope later, update or replace the Make connection and approve the expanded consent before running the scenario; an existing token does not gain it automatically. The connection cannot inspect or mutate webhook endpoints owned by another OAuth application or user. Perkstar enforces tenant, plan, account state, consent, card type, input validation, idempotency, and rate limits again when a module runs. **Make an API Call** uses the exact scopes granted to that connection: the eight baseline scopes plus only the optional scopes the user selected. The module does not grant every allowed scope merely because the OAuth client permits it, and it cannot call private dashboard routes or switch businesses. ## Data the app can process | Feature | Potential Perkstar data | Why it is used | | - | - | - | | Watch loyalty events | Event ID/type/time, organisation ID, and event-specific customer, card, enrolment, loyalty, purchase, membership, engagement, or booking fields | Start the selected scenario and expose mapping fields. | | Search customers | Customer ID/number, contact/profile fields, consent flags, external reference, and lifecycle timestamps | Return current customers matching optional exact contact/reference/pass filters or Created after. | | Search enrolments or passes | Customer/Card IDs, status, balance/activity values, and available Wallet install URLs | Return current programme relationships matching optional Customer ID, Card, and Status filters. | | Customer actions | Identity, profile, consent, and external-reference fields explicitly mapped by the builder | Create or update the intended customer. | | Loyalty actions | Customer lookup, Card, amount/delta, stable source reference, note, and selected metadata | Enrol, record one compatible activity, redeem, or reverse the original transaction. | | Wallet push | Enrolment, message, resolved merge fields, source event ID, and delivery result | Send one business-authored message to eligible Wallet passes. | | Make an API Call | Request and response fields of the selected supported public v1 operation | Cover a documented operation without a guided module. | Perkstar does not enrich every event with customer email, name, or phone merely to make mapping convenient. Use a search only when current profile data is necessary and authorised. The exact event fields are in the [webhook event catalogue](/reference/webhook-events). ## Where Make can retain data Depending on the scenario, workspace settings, plan, and connected apps, customer data can appear in: * scenario module inputs and output bundles; * execution history and incomplete executions; * webhook queues; * Make Data Stores, variables, aggregators, and error handlers; * copied blueprints, screenshots, or support exports; and * every destination app and its own logs, backups, and retention. Turning a scenario off or revoking OAuth stops future work but does not automatically erase those copies. Configure access and retention in Make and every destination according to the business's policy; do not rely on Perkstar to delete records after they leave its platform. ## Responsibility model ```mermaid theme={null} flowchart LR Customer["Cardholder"] --> Business["Business using Perkstar\nNormally the controller"] Business --> Perkstar["Perkstar\nNormally a processor"] Business --> Make["Make organisation and connected apps\nChosen by the business"] Perkstar --> Make Make --> Destination["Scenario destinations"] ``` The business determines its legal role and purpose for each destination, limits who can edit scenarios or inspect executions, gives required notices, and handles access, correction, deletion, objection, and consent rights across all copies. Perkstar cannot govern a module after data enters Make. ## Consent and messaging * Loyalty enrolment is not automatic email, SMS, advertising, profiling, or Wallet push-marketing consent. * Treat Perkstar consent fields as purpose-specific state, not blanket permission for every scenario destination. * Retain the source, wording, time, and lawful basis needed to support any consent assertion written from another application. * **Send a Wallet push** enforces push-marketing consent. A `403` is a safety outcome, not an error to route around. * Never place passwords, payment-card data, health data, or other sensitive free text in a loyalty note, push, Make variable, Data Store, or support request. ## Minimise and protect 1. Map only fields the next module needs. 2. Prefer opaque Perkstar IDs to copying a full customer profile. 3. Keep production connections and scenarios in the intended Make team; grant edit and execution-history access only to authorised members. 4. Keep the private Make webhook URL, OAuth tokens, Wallet install links, and customer payloads out of logs, screenshots, blueprints, and tickets. 5. Use separate test and live source-reference namespaces. 6. Review routers and error handlers: a failed privacy/consent filter must not fall through to a sending route. 7. Protect Data Stores and destination records with retention/deletion rules, not indefinite defaults. ## Webhook authentication boundary Perkstar signs outbound webhooks with HMAC-SHA256. Because Make exposes parsed JSON rather than the exact signed bytes, the official instant module performs an authenticated server-attestation request before emitting a bundle. Perkstar binds the proof to the app-owned webhook, OAuth application and user, organisation, delivery ID, signing time, signature, and event envelope. The signing secret remains encrypted in Perkstar and is not copied into Make. Keep the unique Make callback URL secret as an additional control. A failed or incomplete attestation must be investigated; do not route around it or map the unverified receiver payload directly. See [Webhooks and instant scenarios](/integrations/make/webhooks). ## Disconnect, deletion, and rights requests Deleting an attached Make webhook removes its corresponding app-managed Perkstar subscription. Revoking the connection stops future authorised API calls. Neither action automatically deletes: * Make execution history, incomplete executions, or queued/processed bundles; * Make Data Store entries or copied scenario/blueprint data; * records created in a CRM, spreadsheet, chat tool, or another destination; or * Perkstar source records the business is otherwise entitled or required to retain. For a rights request, locate data by Perkstar ID and stable external reference, then perform the required export, correction, suppression, or deletion in Perkstar, Make, and every destination. Test this procedure before a live scenario distributes personal data. ## Production review * [ ] Beta access, scenario owner, Make team, Perkstar tenant, and destinations are documented. * [ ] The OAuth connection uses the correct business and no raw API key exists in a module or variable. * [ ] The scenario maps the minimum necessary fields. * [ ] Consent and suppression behaviour is tested. * [ ] Editors, connection users, execution viewers, and Data Store access are restricted. * [ ] Stable references make customer and transaction writes retry-safe. * [ ] Webhook URL secrecy and server-attested delivery rejection are tested. * [ ] Revocation, attached-webhook deletion, queue handling, destination deletion, and rights requests are tested. Report suspected credential exposure, unauthorised access, or a personal-data incident to [privacy@perkstar.co.uk](mailto:privacy@perkstar.co.uk). For an operational failure, follow [Make troubleshooting](/integrations/make/troubleshooting). # Make Source: https://developers.perkstar.co.uk/integrations/make/index Build visual Perkstar scenarios with one instant loyalty-event trigger, guided loyalty modules, searches, and secure OAuth. Make Connect Perkstar loyalty activity to the applications in a Make scenario. The app has one dynamic **Watch loyalty events** instant trigger with 29 event choices, 11 guided actions, two searches, and the required **Make an API call** universal module. Card and event selectors load choices from the connected Perkstar business, so builders normally map names and IDs without copying raw API requests. The official Perkstar app for Make is currently a **private beta**. It is not published in Make's public app catalogue. Access must be enabled by Perkstar for the intended Make organisation; finding a similarly named public app or being on an eligible Perkstar plan does not grant beta access. Authorise one Perkstar business with OAuth. Do not paste an API key into a scenario or share one with a contractor. Choose one loyalty event per instant module, with optional card and live/test filtering where supported. Use guided modules, stable source IDs, idempotent retries, and explicit consent checks in production scenarios. ## Availability | Item | Current position | | - | - | | Make listing | Private-beta custom app; not published in Make's public app catalogue | | Perkstar plan | Growth, Scale, Enterprise, or Franchise | | Connection | Perkstar OAuth; one Perkstar business per Make connection | | Permissions | A Perkstar owner or authorised team member who can connect integrations | | Visible modules | 15: one instant trigger, 11 guided actions, two searches, and one universal API module | | Trigger coverage | 29 public business events through one dynamic **Watch loyalty events** module | Private-beta access and plan eligibility are separate. An eligible business still needs explicit beta access until Perkstar completes Make review and publishes the app. ## Module map ```mermaid theme={null} flowchart LR Perkstar["Perkstar business"] --> Watch["Watch loyalty events\n29 event choices"] Watch --> Scenario["Make scenario\nfilters, routers, and mappings"] Scenario --> Apps["Connected destination apps"] Apps --> Actions["11 guided Perkstar actions"] Scenario --> Searches["2 Perkstar searches"] Scenario --> Universal["Make an API call\nadvanced public v1 operations"] ``` The guided actions cover customer creation and updates, explicit find-or-create and find-or-enrol flows, loyalty earning and redemption, transaction reversal, and consented Wallet pushes. **Make an API call** is for supported public v1 operations that do not yet have a guided module; it does not bypass OAuth scopes, tenant boundaries, plan checks, validation, or consent. ## What stays authoritative Perkstar remains the system of record for customers, enrolments, Wallet passes, loyalty balances, rewards, and outbound events. Make stores scenario configuration, execution records, webhook queues, and any values copied into other modules. | Direction | What happens | | - | - | | Perkstar → Make | A selected Perkstar event sends one bundle to the instant trigger. | | Make → Perkstar | A guided or universal module calls a supported public v1 operation using the selected OAuth connection. | | Make → another app | The scenario sends only the fields its builder maps into that module. | | Another app → Perkstar | The scenario writes only fields accepted by the selected Perkstar module and connected business. | Perkstar cannot inspect or control later modules in a scenario. The business is responsible for the destination app, mappings, lawful purpose, access, retention, and deletion of copied customer data. Read [Data and security](/integrations/make/data-security) before processing personal data or sending marketing messages. ## Start here Review private-beta prerequisites, approve OAuth, and run a controlled first scenario. See every event choice, guided action, search, required input, and important boundary. Learn subscription lifecycle, server-attested delivery verification, retries, duplicate protection, and queues. Diagnose access, OAuth, trigger, module, rate-limit, consent, and incomplete execution failures without exposing secrets. Beta questions are handled through [support@perkstar.co.uk](mailto:support@perkstar.co.uk). Include the Perkstar business name and approximate UTC time, but never send an OAuth token, Make webhook URL, customer payload, or unredacted execution screenshot. # Triggers, actions, and searches Source: https://developers.perkstar.co.uk/integrations/make/modules The complete Perkstar module catalogue for Make, with inputs and safety boundaries. The published review candidate contains 15 visible modules: one instant trigger with 29 event choices, 11 guided actions, two searches, and one universal API module. Dynamic selectors load current active cards and other choices from the selected Perkstar OAuth connection. The app is available by invite link while Make reviews its Marketplace listing. Event payloads can gain new optional fields; map only the fields a scenario needs and handle absent or `null` values. ## Instant trigger **Watch loyalty events** creates one attached Perkstar webhook for the event selected in that module. Use separate trigger modules/scenarios for different event subscriptions; do not subscribe to every event merely to discard most bundles later. The trigger outputs a bundle only after an authenticated Perkstar attestation binds its subscription, OAuth owner, signed delivery headers, timestamp, and event envelope. ### Customer lifecycle | Event choice | Perkstar event | Fires when | | - | - | - | | New customer enrolment | `customer.enrolled` | A customer first joins a loyalty card. | | Customer unenrolled | `customer.unenrolled` | Access to a card ends. | | Customer anonymised | `customer.anonymized` | Perkstar removes the customer's direct identifiers. | | Customer lifecycle group changed | `customer.group_changed` | A customer moves between Perkstar's six exclusive lifecycle groups. | The lifecycle-group event does not represent an operator-created saved segment. Perkstar stores the first classification as a baseline without emitting an event, preventing a newly connected scenario from replaying every customer. ### Wallet, scanner, expiry, and referrals | Event choice | Perkstar event | Fires when | | - | - | - | | Wallet pass installed | `wallet.installed` | Perkstar first observes an Apple or Google Wallet install; Google observation is periodic. | | Card scanned | `card.scanned` | An online Perkstar Scanner lookup successfully resolves a card; offline cache-only lookups do not fire. | | Customer card expired | `card.expired` | One enrolment reaches its effective expiry; a later expiry after extension can produce another event. | | New customer referral | `referral.created` | One customer refers another customer to the same loyalty-card programme. | `referral.created` is customer-to-customer loyalty activity. It is not a merchant, agency, partner, or affiliate-referral event. ### Loyalty activity | Event choice | Perkstar event | Fires when | | - | - | - | | New loyalty transaction | `transaction.created` | A supported loyalty-ledger row commits, including a compensating reversal. | | Coupon redeemed | `coupon.redeemed` | A coupon card is redeemed. | | Reward redeemed | `reward.redeemed` | A reward, offer, voucher, or milestone is redeemed. | | Loyalty tier changed | `tier.changed` | A status, cashback, or discount tier changes. | ### Tickets, gifts, and multipasses | Event choice | Perkstar event | Fires when | | - | - | - | | Ticket purchased | `ticket.purchased` | Paid ticket fulfilment completes. | | Ticket cancelled | `ticket.cancelled` | A ticket event is cancelled. | | Ticket refunded | `ticket.refunded` | A ticket payment is refunded or lost to chargeback. | | Gift card purchased | `gift.purchased` | Paid gift fulfilment completes. | | Gift card redeemed | `gift.redeemed` | Value is spent from a gift card. | | Multipass purchased | `multipass.purchased` | A multipass is purchased or topped up. | ### Memberships | Event choice | Perkstar event | Fires when | | - | - | - | | Membership purchased | `membership.purchased` | A recurring or one-off membership first activates. | | Membership renewed | `membership.renewed` | A recurring membership advances to a new billing period. | | Membership cancelled | `membership.cancelled` | A recurring membership becomes cancelled or incomplete-expired. | ### Engagement | Event choice | Perkstar event | Fires when | | - | - | - | | Feedback submitted | `feedback.submitted` | A customer submits card feedback. | | Automation fired | `automation.fired` | A Perkstar automated-message firing is recorded. | | Broadcast sent | `broadcast.sent` | A Wallet broadcast reaches terminal delivery processing. | ### Bookings | Event choice | Perkstar event | Fires when | | - | - | - | | Booking created | `booking.created` | A booking is created. | | Booking confirmed | `booking.confirmed` | A booking moves to confirmed. | | Booking attended | `booking.attended` | Attendance is recorded. | | Booking marked as no-show | `booking.no_show` | A booking is resolved as a no-show. | | Booking cancelled | `booking.cancelled` | A booking is cancelled. | The diagnostic `webhook.test` event is deliberately excluded. See the [webhook event catalogue](/reference/webhook-events) for every required, optional, and nullable event field. ### Trigger inputs and output | Input | Behaviour | | - | - | | Event | Required. Creates a subscription for exactly one of the 29 event types above. | | Card | Optional. Use it only when the selected event carries a Card ID; otherwise leave it blank. A blank Card accepts the selected event across all cards. | | Include test events | Available on the trigger and off by default. It affects only event types that can carry test activity; enable it only in an isolated test scenario. | Each bundle preserves the common event envelope: stable **Event ID**, dotted **Event type**, source **Created**, **Organisation ID**, and a nested **Event data** collection containing the selected event's fields. **Created** is an integer containing Unix seconds. The nested `data.occurredAt` field is the same business occurrence time in ISO 8601 text form. Neither value is the time Make received or executed the scenario. For booking events, `data.id` stays inside **Event data** and does not replace the outer Event ID. Trigger bundles are snapshots; use a search only when a later step genuinely needs current customer or enrolment state. The module publishes a static synthetic sample so mapping fields are available without reading a real customer's latest event. Live webhook deliveries use the same envelope and still complete Perkstar's server-attested verification before Make emits a bundle. ## Guided actions The guided modules validate common merchant workflows and are preferred over the universal API module. A focused loyalty action filters its Card selector to compatible active programmes and validates a mapped Card ID again at runtime. | Guided action | What it does | Important boundary | | - | - | - | | Create a customer | Creates a customer using the supplied identity fields. | Requires a stable **Unique request ID** and at least one of email, phone, or external reference. Keep the request ID unchanged only when retrying that same create. | | Find or create a customer by external reference | Looks up one exact external reference and creates the customer only when no match exists. | External reference is required and must remain stable in the source system. It does not fuzzy-match email, phone, or name. | | Update a customer | Updates explicitly mapped profile or consent fields on one existing customer. | Requires Customer ID. Map at least one field. It cannot change external reference; omitted fields are not an instruction to blank them. | | Find or enrol a customer in a card | Resolves the customer and returns an existing active customer/card enrolment, or enrols the customer in the selected card. | A revoked or inactive pair is not silently reactivated. Creating a missing customer must be explicitly enabled and pass identity validation. | | Add a stamp or visit | Adds a positive whole number of stamps or visits to an active Stamp or Multipass card. | Requires a stable Source activity ID. Incompatible or inactive cards are rejected. | | Award points | Adds a positive points value, including up to two decimals when the card supports it. | Its selector shows active Points cards. The award cannot exceed 100,000; a stable Source points award ID is required. | | Record a purchase | Records a positive integer minor-unit purchase on an active Cashback or Discount card. | Do not pass a decimal currency amount. A stable Source order or payment ID is required. | | Redeem loyalty balance | Deducts a positive whole-number balance or prepaid visit without allowing the balance below zero. | Supports active Stamp, Points, Cashback, and Multipass cards; it excludes Coupon, Membership, Discount, Gift, and Ticket flows. | | Record loyalty activity (advanced) | Selects a compatible `STAMP`, `REDEEM`, `CHECK_IN`, `DISCOUNT`, or `POINTS` activity dynamically. | Card, activity type, and stable Source transaction ID are required. Prefer a focused module when the activity type is known. | | Reverse a loyalty transaction | Writes one compensating transaction for an eligible marketplace transaction found by Perkstar transaction ID or its stable original reference. | A transaction can be reversed once. The module does not edit or delete the original ledger row and does not infer partial-refund policy. | | Send a Wallet push | Sends a plain-text message of up to 180 characters to one enrolment's eligible Wallet passes. | Enrolment and stable Source event ID are required. Push-marketing consent and a three-minute per-card cooldown are enforced; API success cannot guarantee device display. | ### Loyalty identity and retries For **Add a stamp or visit**, **Award points**, **Record a purchase**, **Redeem loyalty balance**, and **Record loyalty activity (advanced)**, keep the source module's order, payment, attendance, or redemption ID unchanged when Make retries an incomplete execution. Perkstar gives each module/operation its own deduplication namespace and permanently binds the canonical source reference to the first customer, card, operation, and amount. An exact retry returns the original result. Reusing that reference with different inputs produces a conflict instead of changing the first transaction. Do not replace a stable source ID with `now`, a random UUID, or a new Make execution ID on retry. The Wallet push supports `{firstName}`, `{lastName}`, `{balance}`, `{cardName}`, `{installLink}`, `{shareLink}`, and `{orgName}` merge fields. Map the source bundle's stable record or event ID into **Source event ID** so repeated handling of one event is collapsed inside Perkstar's idempotency window. ## Searches | Search | Matching behaviour | Result | | - | - | - | | Search customers | Optional exact email, phone, external reference, or pass barcode/serial filters, plus an optional Created after. | Current matching customers, up to the configured Limit. | | Search enrolments or passes | Optional Customer ID and Card filters. Status defaults to Active even when the field is left blank or an empty value is mapped. | Active enrolments, balance/activity values, and available Apple/Google Wallet links, up to the Limit. Choose Inactive or Revoked when historical passes are needed. | Searches do not create or change data. If a no-match should create a customer, use **Find or create a customer by external reference** with a genuine stable external reference. If it should create a card relationship, use **Find or enrol a customer in a card**. Keep a Make router/filter for business outcomes that should stop, notify an operator, or follow a different path on no match. Both searches cursor-page and return no more bundles than **Limit**. Limit defaults to 10 and accepts 1–3,200. Dynamic Card selectors return up to 500 active cards. Their Limit defaults to 200 and accepts 1–500. General selectors show every active card within that limit; focused action selectors show only compatible card types. A manually mapped ID still goes through the same tenant, active, and type checks when the module runs. ## Make an API call **Make an API call** is the universal module required for a public Make app. Use it only when the operation exists in Perkstar's [public API reference](/api-reference/customers/list-customers) and no guided module fits. * Enter a path relative to `https://dashboard.perkstar.co.uk/api/v1`, for example `/customers/{customerId}`. Do not enter a different host or a full callback URL. * Select the supported HTTP method and supply only the documented query string and JSON body. The module supplies OAuth authentication and deliberately does not expose arbitrary request headers. Keeping authentication and transport control headers app-owned prevents a scenario from replacing the OAuth credential, host, content type, or other security-sensitive values. * For a supported POST, map a stable value of at most 255 characters into the optional dedicated **Idempotency key** field. The app sends it only as `Idempotency-Key`; a random value per Make retry can duplicate a write. * The exact scopes granted to the connection still apply. Guided connections use eight baseline scopes; five additional advanced scopes are optional and require explicit selection and renewed OAuth consent. The module cannot access private dashboard routes, another Perkstar business, or an operation outside that connection's granted scopes. * Handle `4xx`, `429`, and `5xx` responses deliberately. Prefer a guided module for loyalty writes because it also constructs and validates the permanent source transaction identity. A universal API module is not a security or product-boundary escape hatch. Do not use it to recreate an unsupported card editor, bulk-marketing sender, or undocumented dashboard workflow. ## Deliberately not exposed * No module edits card configuration, rewards, tiers, coupons, or orders. * No module bypasses Perkstar consent, plan, card-type, tenant, account-state, or rate-limit checks. * `webhook.test` is not a choice in **Watch loyalty events**. * An event bundle does not promise customer email, name, or phone unless the documented event carries it. * Searches and dynamic selectors never read another business connected to the same Make organisation. # Make scenario recipes Source: https://developers.perkstar.co.uk/integrations/make/recipes Reliable Perkstar scenario patterns for onboarding, loyalty activity, operations, and consented Wallet messaging. These are private-beta patterns, not public one-click Make templates. Build them with the named modules, test with controlled records, and define an error route before processing production customers. ## Send a new member to a CRM or sheet **Trigger:** Watch loyalty events → New customer enrolment **Then:** Make an API Call (`GET /customers/{customerId}`) → create or update the destination record 1. Select a Card in the trigger if the destination represents one programme. 2. When **Event Data** includes Customer ID, use it in the relative API path; do not make a second identity guess from name, email, or phone. Route an event with no Customer ID to review or a workflow that can resolve its documented enrolment context. 3. Make the read only when the destination genuinely needs current profile fields. **Search customers** does not accept Customer ID; it is for optional exact email, phone, external-reference, pass-serial, and Created after filters. 4. Use the Perkstar customer or enrolment ID as the destination's stable external key. 5. Add a route for a `404` or missing Customer ID rather than creating an unidentified destination record. Joining a loyalty card is not blanket consent for email, SMS, advertising, or another app's marketing list. Map purpose-specific consent only when the business has evidence for that destination and channel. ## Create an external lead once, then enrol them **Trigger:** A qualified lead, booking, or checkout in another Make app **Actions:** Find or Create a Customer by External Reference → Find or Enrol a Customer in a Card 1. Map the source app's immutable customer/contact ID into **External Reference**. Namespace it when multiple stores can produce the same value, for example `hubspot:portal-42:contact:1042`. 2. Map only the identity/profile fields authorised for Perkstar. 3. Select the intended active Card explicitly. 4. Map the returned customer into **Find or Enrol a Customer in a Card**. 5. Store returned Customer ID and Enrolment ID in the source system where possible. 6. If Wallet links are initially unavailable, use **Search enrolments or Passes** later with Customer ID, Card, and Active status instead of constructing a link. This pattern makes a repeated source event return the same customer and active customer/card relationship. It never silently reactivates an inactive or revoked enrolment. ## Record a paid order exactly once **Trigger:** A paid or completed order in a commerce/POS module **Action:** Add a stamp or visit, Award points, or Record a purchase Choose the focused action that matches the Perkstar card: | Card intent | Guided module | Amount | | - | - | - | | Stamp or visit credit | Add a stamp or visit | Positive whole-number count | | Direct points award | Award points | Positive points value | | Cashback/discount spend | Record a purchase | Positive integer minor units, such as `1250` for £12.50 | Map the upstream order/payment ID into the action's Source ID. Prefix it when several stores can emit the same numeric ID: ```text theme={null} shopify:store-12:order:94721 ``` Use a Make error handler that keeps that value and every fingerprinted input unchanged on retry—including customer identity, Card, activity type, amount, note, metadata, and create-if-missing fields. If the scenario needs to choose an activity type dynamically, use **Record loyalty activity (advanced)** and validate Card, type, delta, and purchase amount on every route. Never generate a new source transaction ID when an incomplete execution is retried. A stable upstream ID is what prevents a delayed or duplicate order bundle from crediting loyalty twice. ## Reverse a refunded order **Trigger:** A completed refund in the source app **Action:** Reverse a Loyalty Transaction Prefer the Perkstar transaction ID returned and stored by the original earn scenario. If only the original source order/payment ID is available, use the same value and the exact original Perkstar operation when the module asks for it. Perkstar writes a compensating ledger row and returns the existing reversal when the same original transaction was already reversed. Partial-refund rules vary. Decide whether a partial refund should leave the original loyalty transaction, reverse it fully, or be handled by a separate approved adjustment before activating the scenario. The reversal module does not infer this policy from arbitrary refund data. ## Route an operational loyalty event **Trigger:** Watch loyalty events → Reward redeemed, Loyalty tier changed, Feedback Submitted, Booking Marked as No-Show, or another selected event **Then:** Filter → approved operations channel or case-management app Include the Perkstar event ID, source time, and only the opaque customer, enrolment, booking, or card ID an authorised operator needs. Avoid copying full contact details or free-text feedback into a broad channel. Use separate trigger modules/scenarios for materially different access and retention rules. ## Send a consented Wallet reminder **Trigger:** A deliberate business rule in another app **Actions:** Search enrolments or passes → Send a Wallet push * Target one current enrolment. * Map the upstream bundle's stable event/record ID into **Source Event ID** and preserve it across retries. * Keep the expanded message at or below 180 characters. * Expect `403 push_marketing_consent_required` when consent is absent; route it to a safe stop, not a workaround. * Respect `Retry-After` and the shared three-minute per-card cooldown on `429`. * Do not iterate a large customer list into rapid sends without an approved frequency cap and queue. ## Use Make an API Call without duplicating a write Use **Make an API Call** only for a documented public v1 operation without a guided module. 1. Confirm the operation and schema in the [API reference](/api-reference/customers/list-customers). 2. Use the relative path, never another host. 3. For supported POST requests, map a stable upstream value of at most 255 characters into the optional dedicated **Idempotency Key** field, and keep it unchanged for every retry of that logical request. 4. Add an error route for `429` and transient `5xx` results. 5. Treat `400`, `403`, `404`, `409`, and `422` as state or validation problems, not blind-retry candidates. 6. Inspect the Perkstar record after a timeout before changing any identifier. Prefer a guided module whenever it exists. The universal module cannot add product-specific card filters or construct the permanent source transaction identity as safely as the focused loyalty actions. ## Production checklist * [ ] The Make organisation, team, scenario owner, Perkstar business, and every destination owner are recorded. * [ ] Each connection name identifies the tenant and environment. * [ ] Each instant trigger selects one event and an explicit Card where useful. * [ ] Every loyalty write uses a stable source ID and survives a duplicate test. * [ ] Routers handle empty search results and optional event fields. * [ ] Error handlers preserve original IDs and expose terminal failures to an operator. * [ ] Consent and suppression are tested with both allowed and blocked records. * [ ] `429`, non-retryable `4xx`, incomplete executions, and destination failures are monitored. * [ ] Scenario history, webhook queues, Data Stores, and destinations have intentional retention and access. * [ ] Disconnect, rights-request, incident, and downstream deletion procedures have named owners. For failures, use [Make troubleshooting](/integrations/make/troubleshooting). # Connect Perkstar to Make Source: https://developers.perkstar.co.uk/integrations/make/setup Get private-beta access, authorise Perkstar with OAuth, and test a controlled first Make scenario. The private-beta app uses Perkstar OAuth. The person creating the connection signs in to Perkstar, confirms the intended business, reviews the requested access, and approves it. Make receives revocable OAuth tokens; the builder is never asked to paste a Perkstar API key into a scenario. Perkstar for Make is not yet public in Make's app catalogue. Use only the private app access supplied by Perkstar. A similarly named app or setup page that asks for a raw Perkstar API key is not the official connection flow. ## Before you connect * The Perkstar business is on Growth, Scale, Enterprise, or Franchise. * Perkstar has enabled the intended Make organisation for the private beta. * You can sign in to both the intended Perkstar and Make accounts. * Your Perkstar role can connect integrations for the business. * Your Make role can create connections and edit scenarios in the intended team. * At least one active loyalty card exists for card-aware modules and filters. * You know who will own the scenario and which customer fields each destination needs. One Make connection represents one Perkstar business. Create a separately named connection for every business; a connection never searches or writes across Perkstar tenants. ## Create the connection Sign in to the Make organisation that Perkstar enabled and create or open a scenario in the correct team. Add a module, search for **Perkstar**, and select a trigger, action, or search. Beta access makes the private app available to that organisation; it does not publish the app or activate a scenario. In the module's **Connection** field, choose **Add**. Make opens Perkstar's hosted authorisation page over HTTPS. Check the business and signed-in account shown by Perkstar. If either is wrong, cancel and switch Perkstar organisation before approving. Do not authorise first and rely on a later module filter to isolate another business. Read the plain-language permissions and choose **Allow** only if they match the intended scenario. The private-beta app requests customer, enrolment, card, event, webhook, marketplace-loyalty, and Wallet-push permissions used by its guided modules. If the connection offers **Advanced API scopes**, leave them unselected unless a documented **Make an API call** operation requires one; each selected scope appears on the Perkstar consent screen. Perkstar returns the connection to Make without displaying an API key. Use a name that identifies the tenant, for example `Perkstar — North Street Coffee (Live)`. Open the module again and confirm card selectors and a safe search return data only from that business. The Make OAuth client allows five optional advanced scopes for documented enrolment writes, transaction reads/writes, app-owned webhook reads, and location reads. They are not part of an ordinary guided connection. Read [OAuth permissions](/integrations/make/data-security#oauth-permissions) before requesting one. Adding a scope later requires renewed consent; Make cannot add it silently to an existing grant. ## Test a read-only scenario first Select **Search customers**, choose the new connection, and use an authorised internal test customer's exact email, phone, external reference, or pass barcode/serial. You can also filter by **Created after**. Use a narrow Limit for this connection test; Customer ID is not an input to this search module. Choose **Run once** in Make. Open the module's output bundle and confirm the customer ID and business-owned fields are the expected record. A no-match result is not permission to guess another tenant's identifier. Map only the fields a low-risk destination step needs. Keep the scenario inactive until its filters, error handler, access, and data retention have been reviewed. ## Test the instant trigger Add **Watch loyalty events** as the first module, create its attached webhook, and select one event. Choose a Card only when that event carries a Card ID and the scenario belongs to a single programme. Leave test events excluded unless this is an isolated test scenario. Choose **Run once**, then perform the exact low-risk event in the connected Perkstar business. A generic `webhook.test` diagnostic does not satisfy the module's business-event selection. Confirm the trigger's authenticated Perkstar verification request succeeded, then inspect the stable outer Event ID, dotted Event Type, Created timestamp, Organization ID, and nested Event Data before mapping another module. Optional Event Data fields can be absent or `null`. Add filters and an error handler, save the scenario, then schedule it **On** for one event/card and a narrow audience. Monitor Make scenario history, incomplete executions, and the corresponding Perkstar records before widening it. ## Connection and webhook lifecycle | Change | Effect | | - | - | | Rename a connection | Changes its Make label only; the OAuth grant remains bound to the same Perkstar business. | | Reauthorise a connection | Future modules use the renewed OAuth grant. Retest every active scenario that uses it. | | Revoke access in Perkstar | Future API calls fail and app-owned subscriptions can no longer be managed until a valid connection is restored. | | Turn a scenario off | Stops normal scenario processing, but does not necessarily delete its attached Make webhook. Check the scenario and Make webhook queue before assuming the Perkstar subscription is gone. | | Delete the attached webhook | The app's detach step deletes the corresponding app-managed Perkstar subscription. Historical Make executions remain under Make's retention settings. | | Delete a destination connection | Does not remove records the scenario already copied into that destination. | To revoke Perkstar access, open **Settings → Authorised apps** in the connected Perkstar business and revoke the Make connection. Then remove or reauthorise the connection in Make before reactivating affected scenarios. Read [Webhooks and instant scenarios](/integrations/make/webhooks) before using an event trigger, [Troubleshooting](/integrations/make/troubleshooting) before reconnecting a shared production connection, and [Data and security](/integrations/make/data-security) before mapping personal data. # Make troubleshooting Source: https://developers.perkstar.co.uk/integrations/make/troubleshooting Diagnose private-beta access, OAuth, instant triggers, modules, queues, retries, rate limits, and consent failures. Start with the scenario's execution history, incomplete executions, and the connected Perkstar business. Record the module name, UTC time, status/code, and Perkstar `X-Request-Id` before retrying. Never copy an OAuth token, Make webhook URL, or full customer bundle into a support message. ## Access and connection The app is a private beta and is not publicly searchable in Make's app catalogue. Confirm that Perkstar enabled the Make organisation you are currently using. An eligible Perkstar plan alone does not grant beta access. Make access requires Growth, Scale, Enterprise, or Franchise. Check the current plan and that OAuth is opening the intended business. Free and Starter businesses cannot connect the integration. Cancel instead of approving. Switch to the correct Perkstar organisation, then add a new connection. A later Make filter cannot change the tenant bound to an OAuth grant. Reopen the module and select the newly created connection explicitly. Make connections belong to a team context; confirm the scenario is in the team where the connection was created and that your Make role can use it. Reauthorise it once, then run a read-only **Search customers** test. If Perkstar access was revoked, a new consent is required; retrying the old execution cannot restore the grant. Retest every active scenario sharing that connection. ## Watch loyalty events Start **Run once** before performing the event. Confirm the module selected the exact dotted business event, correct Perkstar connection, and correct Card when a Card filter is set. The generic `webhook.test` diagnostic is not one of the module's 29 event choices. Confirm the scenario is saved and On, its attached webhook still exists, the OAuth connection is authorised, and the business operation actually reached a completed state. Inspect Make's webhook queue, execution history, and incomplete executions. If no bundle exists, report the event ID and UTC time to Perkstar support without sharing the callback URL. Turning a scenario Off does not necessarily delete its attached webhook. Make can retain webhook state or queued bundles depending on configuration. Inspect timestamps and the webhook queue before processing; delete the attached webhook if the upstream subscription should end. Perkstar delivery is at least once. Compare the stable event ID. Add a uniqueness check or Make Data Store guard before a non-idempotent destination write, and use the same ID as the downstream source reference. This is allowed. Compare Event Data `occurredAt` or the outer Created value and the current destination state. Do not order business changes by Make execution time. Event bundles are not enriched with a full customer profile, and optional fields do not apply to every occurrence. Review the [event catalogue](/reference/webhook-events), guard mappings, and add **Search customers**, **Search enrolments or passes**, or a documented read through **Make an API call** only when current state is appropriate. Creating a pass or opening a save link is not installation evidence. Apple normally reports a device registration. Google is observed periodically; provider response, object age, and projector backlog can extend the delay. A business's first Google subscription uses a completed sweep as a no-event baseline, so enable and test before distributing install links. **Card Scanned** covers successful online Perkstar Scanner lookups only. A cache-only offline scan, dashboard search, or POS customer lookup does not cross the webhook boundary. The event reports movement among Perkstar's six lifecycle groups, not entry into a saved segment. Initial classification is stored as a no-event baseline to avoid replaying the customer base. ## Searches and actions | Symptom | Likely cause | What to do | | - | - | - | | Search customers returns no bundle | Exact email, phone, external reference, pass serial, or Created after filter does not match | Correct or remove the filter and keep a narrow Limit. Use `GET /customers/{id}` for a known Customer ID. | | Search enrolments or passes has no Wallet URL | Pass issuance is pending, filters do not match, or that Wallet platform is not configured | Check Customer ID, Card, and Status; retry later and never construct an install URL. | | Find or Enrol reports inactive/revoked | That customer/card pair exists and Perkstar will not silently undo its status | Review and explicitly reactivate it in Perkstar; do not create a duplicate customer. | | A Card is absent from a focused module | The card is inactive or its type is incompatible | Choose the matching module/card type. Manually mapped incompatible IDs are rejected too. | | `400 ambiguous_default_card` | Several active cards exist and none was selected | Select the intended Card explicitly. | | `401` or connection error | OAuth grant is invalid, expired beyond refresh, or revoked | Reauthorise, run a read-only test, then retest every affected scenario. | | `403` permission error | Grant lacks the operation's scope, plan/role is ineligible, or the operation is forbidden | Reauthorise the official connection and confirm plan/role. Never substitute a raw API key. | | `403 push_marketing_consent_required` | Customer lacks Wallet push-marketing consent | Stop the message and follow the approved consent process; do not route around it. | | `404` | Customer, enrolment, card, or transaction is not in this business or no longer exists | Check the connection and opaque IDs; do not reuse an ID from another tenant. | | `409` creating a customer | A conflicting customer exists and no stable external-reference upsert was used | Find the existing customer or use the source system's genuine stable external reference. | | `409 external_transaction_id_conflict` | A source ID was reused with different customer, card, operation, or amount | Keep original inputs for a retry, or use the different source record's own ID. | | `409 webhook_subscription_limit_reached` | This Make app, installing Perkstar user, and business share 200 subscriptions, including paused rows | Remove unused Make webhooks, confirm detach, then create the new webhook again. | | `422` loyalty validation | Activity/amount does not match the Card type, or a source reference belongs to the other environment | Correct the mapping. Do not hide the error by generating a new source ID. | | `429` | API limit or three-minute Wallet-push card cooldown | Honour `Retry-After`; reduce iterators, concurrency, and bursts. | | `5xx` or network timeout | Temporary Perkstar or network failure | Retry the same logical operation with unchanged stable IDs; check [API status](/support/status). | ## Make an API call | Symptom | What to check | | - | - | | Invalid or unsupported URL | Use a relative public v1 path such as `/customers/{id}`. Do not pass a full host or private dashboard path. | | Missing authentication | Select the Perkstar connection. The module supplies OAuth and has no arbitrary-header input. | | Duplicate POST after retry | Map the same stable value (up to 255 characters) into **Idempotency Key** on every attempt and inspect whether the first call succeeded. | | Guided module succeeds but universal call returns `403` | The connection did not grant the required optional permission, or the operation is not available to that business or scope. | | Response body does not match a mapping | Confirm the current public API schema and guard optional fields; do not assume a dashboard response shape. | ## Incomplete executions and safe replay Before resolving or replaying an incomplete Make execution: 1. Decide whether the earlier Perkstar or destination module may already have succeeded. 2. Preserve the original source event, order, payment, activity, or request ID, and keep every mapped field that contributes to the request fingerprint unchanged—including customer identity, Card, activity type, amount, note, metadata, and any create-if-missing fields. 3. Fix non-retryable validation, permission, consent, or conflict errors first. 4. Retry the failed path once and inspect the returned Perkstar record. 5. Confirm no iterator/router path can execute the same write again with a new source ID. To reverse a loyalty write, prefer its returned Perkstar Transaction ID. If only the upstream source ID is available, use the exact original reference and operation expected by **Reverse a loyalty transaction**. ## Webhook attestation failure The official trigger sends the received event and signed headers back to Perkstar over OAuth before it outputs a normal bundle. If that check fails, do not map around it: confirm the attached webhook still belongs to the selected connection, the event was not altered, the execution is recent, and the Perkstar business and OAuth grant remain active. Keep the callback URL secret. A temporary verifier outage can leave a Make execution failed or incomplete after its callback was already acknowledged. Resume the same execution after service recovers and preserve the original Event ID. Exact proofs remain recoverable for up to 90 days; older proofs fail closed. See [Webhooks and instant scenarios](/integrations/make/webhooks). ## Ask for help Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with: * the Perkstar business name; * the Make organisation/team and scenario name (not a private link); * the Perkstar module and approximate UTC time; * the Make execution ID and Perkstar `X-Request-Id`, event ID, or delivery ID when available; and * the status/error code with secrets and personal fields removed. For suspected credential exposure or a personal-data incident, contact [privacy@perkstar.co.uk](mailto:privacy@perkstar.co.uk) immediately. # Webhooks and instant scenarios Source: https://developers.perkstar.co.uk/integrations/make/webhooks Understand Make attached webhooks, server-attested delivery verification, retries, duplicate protection, and queues. **Watch loyalty events** is an instant trigger backed by a Make attached webhook. When its webhook is created, the app registers the unique Make HTTPS callback with Perkstar for one event and optional Card/live-test filters. Perkstar sends matching events as they happen; the module does not poll customer or transaction lists. Let the official module create and manage its subscription. Do not also copy a custom Make webhook URL into Perkstar for the same event unless two independent deliveries are an intentional, reviewed design. ## Attached webhook lifecycle The module sends one create request containing Make's unique HTTPS callback, the selected event and filters, and active state. Perkstar returns the subscription ID that Make stores for detach; there is no separate activation request. A retried create uses the same deterministic callback identity to recover the live row instead of creating another subscription. Perkstar durably creates a delivery before scheduling the outbound POST. Events that do not match the event type, Card, or live/test selection are rejected before an outbound delivery is created. An HTTP `2xx` acknowledges the delivery. Acceptance by Make proves only that its webhook endpoint received the bundle; inspect scenario history and incomplete executions to confirm downstream modules completed. Deleting the attached webhook invokes the app's detach operation and deletes that app-owned Perkstar subscription. Recreating it produces a new callback relationship. Scenario and destination history are not erased. Turning a scenario **Off** and deleting its attached webhook are different operations. Do not assume an inactive scenario has already removed the Perkstar subscription. Check the scenario's webhook configuration and Make's webhook queue, then delete an unused attached webhook deliberately. One Perkstar OAuth application, installing Perkstar user, and business combination can own up to 200 Perkstar webhook subscriptions. Multiple Make connections authorised by that same Perkstar user for that business share the allowance. Paused rows left by interrupted cleanup or a revoked grant still count, and each **Watch loyalty events** webhook normally uses one. At the limit, remove unused attached webhooks and confirm detach succeeded; Perkstar returns `409 webhook_subscription_limit_reached` rather than replacing another scenario's subscription. Perkstar binds subscription idempotency to the live row rather than a short response cache. A lost create response, access-token refresh, or repeated attach call with the same app identity can recover that row. Deleting it releases the identity and capacity immediately. The first Customer Lifecycle Group Changed or Google Wallet Pass Installed subscription for a business needs one completed warm-up sweep. Perkstar stores existing state without replaying the customer base, then tracks later changes. Apple installation remains callback-driven. ## Event identity Perkstar sends this common envelope: ```json theme={null} { "id": "whd_01JEXAMPLE", "type": "transaction.created", "created": 1785312000, "orgId": "org_123", "data": { "enrollmentId": "enr_123", "type": "STAMP", "delta": 1, "occurredAt": "2026-08-02T10:00:00.000Z" } } ``` `id` and `X-Perkstar-Delivery-Id` identify one logical delivery and stay stable across automatic retries. `created` is the source event's `data.occurredAt` expressed as Unix seconds, not the delivery-attempt time. Different events can arrive out of order. Use the event ID as the scenario's duplicate key. If a destination write is not naturally idempotent, record processed IDs in a destination uniqueness constraint or a Make Data Store before the write. Do not assume Make will deduplicate two accepted deliveries automatically. ## Delivery policy | Attempt | Timing | | - | - | | 1 | Immediately | | 2 | 1 minute after the first failure | | 3 | 5 minutes after the second failure | | 4 | 30 minutes after the third failure | * Any HTTP `2xx` response succeeds. * A non-`2xx`, network failure, or response taking longer than ten seconds schedules the next attempt. * `410 Gone` permanently exhausts that delivery and pauses the Perkstar subscription. * After four failed attempts, the delivery is exhausted and retained for support diagnostics. * Delivery is at least once. Every route and destination write must tolerate a duplicate. * Perkstar retries only when delivery to Make fails. If Make accepted the bundle and a later scenario module failed, resume or retry the Make execution with the same source identifiers. * Use `data.occurredAt` or outer `created` for business ordering, not arrival time or Make execution time. ## Server-attested delivery verification Perkstar signs every outbound request with HMAC-SHA256 and sends `X-Perkstar-Signature: t=,v1=`. Make exposes the parsed JSON event to a custom app rather than the exact original bytes, so the official module does not attempt to recreate the raw-body HMAC inside Make. Instead, **Watch loyalty events** sends the received event and signed delivery headers back to Perkstar over the tenant-scoped OAuth connection before it outputs a bundle. Perkstar verifies the app-owned subscription, organisation, authorising user, delivery ID, signing time, stored signature proof, and exact event envelope. A missing, stale, forged, cross-tenant, or altered delivery is rejected and does not become a normal scenario bundle. The per-subscription signing secret remains encrypted in Perkstar and is never stored by Make. Treat the callback URL as a secret as an additional defence: never log it, paste it into a ticket, expose it in a screenshot, or reuse it as a public endpoint. The stable event ID remains the duplicate key; verification proves origin and integrity but does not turn at-least-once delivery into exactly-once processing. Make acknowledges the incoming HTTP delivery before the scenario's authenticated verification step finishes. A temporary Perkstar verification outage therefore appears in Make as a failed or incomplete execution rather than causing Perkstar to resend an already accepted callback. Resume that execution with the same event ID after service recovers. The exact stored proof remains recoverable for up to 90 days, matching Perkstar's terminal webhook-delivery retention; proofs older than that are rejected. Normal duplicate handling by Event ID is still required when an execution is resumed or replayed. ## Test an instant scenario 1. Add **Watch loyalty events** as the first module. 2. Select the intended Perkstar connection and create its attached webhook. 3. Choose exactly one Event and, only when that event carries a Card ID, the intended Card. 4. Keep **Include Test Events** off for a live scenario. 5. Choose **Run once**, then perform the exact event in Perkstar. 6. Confirm the module completed its Perkstar verification request, then inspect the event ID, event type, organisation, source time, and relevant fields inside **Event Data** before mapping another module. 7. Stop **Run once**, add duplicate/error handling, save, and turn the scenario on only after the test result is understood. The `webhook.test` diagnostic is not an Event choice. A sample bundle is not a promise that every optional field will be populated on later events. ## Observation boundaries * **Wallet Pass Installed** fires on first provider-owned installation evidence. Apple reports device registration directly. Recently issued Google passes are eligible for a periodic projector; object age, provider response, and backlog can extend the delay. Issuing a pass or opening a save link is not installation evidence. * **Card Scanned** covers successful online Perkstar Scanner lookups only. An offline cache lookup, dashboard search, or POS lookup is outside the event. * **Customer Card Expired** belongs to one enrolment and effective expiry. If an extension later reaches a new expiry, another event is expected. * **Customer Lifecycle Group Changed** tracks movement among six Perkstar lifecycle groups, not saved-segment membership. Initial classification is a suppressed baseline. * **New Customer Referral** is one loyalty customer referring another. It is not a merchant, agency, partner, or affiliate invitation. Some bundles contain purchaser or customer data. Make execution history, queues, Data Stores, and every mapped destination can retain those values. Read [Data and security](/integrations/make/data-security) before activating the scenario. # Meta Pixel Source: https://developers.perkstar.co.uk/integrations/meta-pixel/index Configure Meta Pixel measurement for supported customer journeys. Send supported customer journey events to your business's Meta Pixel account. This is measurement, not a loyalty balance source or proof that a message was delivered. ## Configure the connection 1. Select the intended business in **Perkstar → Integrations → Meta Pixel → Connect**. 2. Enter the **Pixel ID** and **Conversions API token** from the property or data source you control in Meta Events Manager. 3. Save in the integration workspace. These are business-level settings inherited by its cards; do not paste a different business's credentials into a card. 4. A saved-secret hint means the secret is already stored. Leaving it untouched preserves it; entering a replacement deliberately updates it. ## Check an event Use a controlled test customer and a supported enrolment or loyalty journey with the required recorded marketing consent. Inspect the matching event in Meta Events Manager. The implementation requires both the identifier and secret, plus the applicable consent, before firing these events. A saved identifier alone is not a completed verification. ## Troubleshooting and ownership Check the correct business, identifier, saved secret and test customer's consent. Provider reporting can differ from Perkstar transaction totals; attribution events are not the accounting record. Do not remove consent requirements to make a test appear. Keep secrets private and rotate them through the provider when necessary. Use the available workspace controls to remove the configuration when retiring it, then confirm with a controlled test that no new event is generated. See [security and privacy](/fundamentals/security-privacy). # Mindbody Source: https://developers.perkstar.co.uk/integrations/mindbody/index Availability and next steps for Mindbody. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Connect a studio to reward eligible class and appointment attendance. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Mindbody. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # MX POS Source: https://developers.perkstar.co.uk/integrations/mx-pos/index Availability and next steps for MX POS. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Configure MX POS transaction polling and card routing when the connector is released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect MX POS. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # PAX Source: https://developers.perkstar.co.uk/integrations/pax/index Availability and next steps for PAX. **Unavailable.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. PAXSTORE manages terminal fleets but does not provide the transaction feed this Perkstar connection needs. This is not a supported way to connect PAX sales to loyalty. ## What to do now Open **Perkstar → Integrations** and inspect PAX. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # GoDaddy Poynt Source: https://developers.perkstar.co.uk/integrations/poynt/index Availability and next steps for GoDaddy Poynt. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Configure a Poynt business for sales polling and customer matching when released. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect GoDaddy Poynt. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Delivery reports and recovery Source: https://developers.perkstar.co.uk/integrations/resend/delivery-recovery Understand email outcomes and recover a stopped or failed send without changing sending accounts silently. ## Read the campaign report Open **Invitation campaigns**, choose the campaign and check which sending account the run used. A connection status and an individual message outcome answer different questions. | Outcome | What it means | | - | - | | Queued or waiting | Delivery has not finished; the next check time is not a delivery promise | | Excluded or held before sending | The address was not submitted. A quality verdict is not a bounce | | Provider accepted | Resend accepted the request; it does not prove inbox placement or reading | | Delivered | Resend reported delivery; it does not prove reading | | Bounced or failed | The provider reported rejection or failure; inspect its reason | | Uncertain | Perkstar cannot safely establish the outcome yet; do not assume it is unsent | A later bounce can follow an earlier accepted or delivered event. Read the outcome and provider evidence together rather than adding every historical status as a separate recipient. ## Retry deliberately Connecting Resend does not restart a stopped campaign. Review the remaining recipients and the selected sending account before choosing a supported retry. Previously accepted invitations and uncertain deliveries retain their original provider record; changing accounts is not a way to resend them automatically. Consent, unsubscribe and duplicate protection remain enforced. When using your own Resend account, Perkstar does not buy an Emailable check or apply its shared address-quality verdicts and bounce-rate pauses. Your own Resend account can still suppress an address, exhaust a quota or reject a message under its policies. A Perkstar suspension or unrelated abuse restriction still applies. ## Disconnect or replace the account Open **Integrations → Resend → Manage Resend** and choose **Disconnect Resend**. This stops use of the saved sending key. It does not recall accepted emails. Sending remains unavailable until a replacement connection is explicitly activated; Perkstar does not silently switch these messages to its shared sender. You can also revoke the named Perkstar key and remove its webhook in Resend. Removing the webhook stops later delivery updates. Retain the relevant records while reconciling any pending or uncertain messages. ## What to give support Business account number, campaign name or reference, the approximate time, selected sender, visible error and the provider's message ID if available. Do not include API keys, webhook secrets or a full customer list. See [connection setup](/integrations/resend/setup) and the [email sending terms](https://dashboard.perkstar.co.uk/email-provider-terms). # Resend Source: https://developers.perkstar.co.uk/integrations/resend/index Connect your own sending account, verify delivery and manage customer invitation emails. Send supported customer invitations and card-install links using your own Resend account and verified domain. Manage the connection inside **Perkstar → Integrations → Resend**. This is a business integration; white-label ownership is not required. Prepare your domain, connect, test delivery and choose when to activate. Check what was accepted, delivered, held or bounced, and recover without duplicating invitations. ## Choose a sending account | | Perkstar's shared service | Your connected Resend account | | - | - | - | | Sending account and domain | Perkstar's | Yours | | Emailable address checks | Applied to supported shared sending | Not used; no Perkstar verification credits spent | | Shared quality exclusions and bounce-rate pauses | Apply | Do not apply | | Shared invitation allowance | Applies | Does not apply; your provider quotas and other feature entitlements remain | | Consent, unsubscribe and duplicate protection | Retained | Retained | | Provider fees and restrictions | Perkstar's service rules | Your Resend contract and quotas | | Connection failure | Reported or held | Held or failed; never silently sent through Perkstar | ## What uses this connection Initial invitations, invitation follow-ups and supported customer card-install emails, including install links for imported customers. Importing a customer record alone does not send an email or prove permission to contact that person. Perkstar sign-in, security and billing emails remain separate. Connecting Resend does not enable the retired manual marketing email composer, send SMS, or configure Klaviyo flows. ## Before you start You need the business owner's own Perkstar login, email-feature access, a Resend account and a verified sending domain. A staff login or Perkstar support preview cannot connect it on your behalf. A closed or suspended account remains blocked. Resend can independently reject, suppress or limit mail from your account. Read the [email sending and connection terms](https://dashboard.perkstar.co.uk/email-provider-terms). Activation is an explicit choice after a signed delivery test. It does not restart a stopped campaign or resend previously accepted invitations. # Connect your Resend account Source: https://developers.perkstar.co.uk/integrations/resend/setup Set up a verified domain and activate email sending inside Perkstar's integrations workspace. The complete flow stays in **Integrations → Resend → Connect Resend**. Its progress steps are **Prepare → Connect → Test delivery → Activate**. ## Have these details ready | Field in Perkstar | What to enter | | - | - | | Sending email address | An address on the exact domain verified for sending in your Resend account, such as `loyalty@mail.example.com` | | Reply-to email address | The mailbox where your team receives customer replies | | Verified Resend domain ID | The ID of that verified domain in Resend, not the domain name | | Temporary full-access setup key | A Resend API key that can inspect the domain and create the connection resources | Use your own domain and mailbox. Do not enter a Perkstar domain, a password or a key belonging to a different business. A domain and its subdomain are different: verifying `example.com` does not satisfy an exact sender check for `mail.example.com`. In your [Resend account](https://resend.com/domains), add the domain you own, follow its DNS instructions and wait until it is verified with sending enabled. Copy its domain ID. Domain verification is completed in Resend; Perkstar does not modify your DNS records. Open [Resend API keys](https://resend.com/api-keys) and create a full-access key for setup. Keep it private. Perkstar uses it to create a separate sending-only key restricted to the verified domain and a signed delivery webhook. Perkstar does not store the temporary full-access key. Sign in as the business owner and confirm the correct business. Open **Integrations → Resend → Connect Resend**, enter the four details and read the connection terms. Tick the acknowledgement, then choose **Connect and test Resend**. This creates the connection resources; it does not activate customer sending. The test goes only to Resend's `delivered@resend.dev` test address. No customer receives it. Choose **Refresh status** while waiting. The connection must reach **Test passed — ready to activate** before you can continue. Provider acceptance alone is not enough: Perkstar requires the signed delivery event for this test. Choose **Use my Resend account**. Confirm that the current sending account now shows your Resend sender. You can revoke the temporary full-access setup key in Resend; retain the named Perkstar sending key and webhook while using the integration. ## Check the result * **Manage Resend** still appears inside the integration workspace. * The selected sending account shows your sender and the connection is connected. * A saved connection is not a guarantee that every future email will be delivered. * No stopped campaign has restarted automatically. Review the campaign separately before deliberately choosing a new send or retry. ## If setup does not finish | What you see | What to check | | - | - | | Domain not verified or inaccessible | Exact sender domain, sending-enabled status, domain ID and access of the temporary setup key | | Waiting for signed delivery confirmation | Refresh status; check the test email and webhook delivery in Resend. Do not activate based only on an accepted event | | Setup needs attention | Read the error. Correct the provider configuration, disconnect the failed connection and reconnect | | Only the owner can manage | Use the actual owner's login, outside a support or impersonation session | | Existing connection | Inspect its status first. Disconnect deliberately before replacing it | Do not post API keys or webhook secrets in screenshots, support messages or shared documents. For a failed test, provide the business account number, time and visible error instead. Continue with [delivery and recovery](/integrations/resend/delivery-recovery). # Setmore Source: https://developers.perkstar.co.uk/integrations/setmore/index Availability and next steps for Setmore. **Not open for new connections.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Sync appointments and credit the customer's wallet after attendance. The current workspace does not offer general self-service setup for this provider. ## What to do now Open **Perkstar → Integrations** and inspect Setmore. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Shopify Source: https://developers.perkstar.co.uk/integrations/shopify/index Connect the intended store and verify order, location and loyalty routing. Reward eligible online and POS orders with customer matching, order reconciliation and refund recovery. Availability is beta and depends on configuration and the business's integration entitlement. ## Connect and choose the store 1. Open the intended business in **Perkstar → Integrations → Shopify**. 2. Choose **Connect** and enter the store details requested by the setup form. 3. Review Shopify's authorisation for the correct store. If Perkstar asks you to choose a business, select it explicitly before continuing. 4. Return to **Manage** and confirm the store account. Review the default programme and location routes before processing customer sales. Do not connect a second store simply to bypass a missing permission or failed setup. Each store's programme and location choices should reflect the business's actual checkout process. ## Check one controlled order Use an authorised test customer who can be matched to the intended programme. Check the eligible paid order, its source reference, Perkstar loyalty transaction and reporting location. Follow a controlled refund through the same records. Repeated source events must not become repeated loyalty credits. A connected store or recent product catalogue sync does not prove that a particular order qualified for loyalty. Check order processing and customer matching separately. ## Recover and disconnect Use the workspace's activity and error details to identify the affected store, order and location. Fix mapping or authorisation before requesting supported recovery. Do not manually credit and replay the same sale without reconciling it. Disconnect in **Manage** when retiring the connection, and confirm any remaining Shopify app installation or separately configured automations in Shopify. For custom integrations, see [customer sync](/guides/customer-sync) and [idempotency](/fundamentals/idempotency). # Earn with Square and redeem in Perkstar Source: https://developers.perkstar.co.uk/integrations/square/earning-redemption Attach an existing Square Customer, award the routed Perkstar programme and understand the separate Perkstar redemption boundary. Square provides the completed sale and refund signals. Perkstar owns the member, loyalty balance, Wallet pass and reward redemption. A seller can start earning through Square's standard customer-attachment path. Wallet QR identification is optional. Customers can redeem eligible rewards themselves from their pass, or staff can use Perkstar Scanner. Neither path requires Square Loyalty or a Square QR scanner. ## Award a completed payment ### Standard customer attachment The customer joins the business's Perkstar programme before their first eligible Square sale. Adding the pass to Apple Wallet or Google Wallet lets them view updates and present the card; installation is not required for email or phone matching to an active enrolment. Use Square's normal customer search and choose the existing Square Customer whose email address or phone number exactly matches the Perkstar member. If both fields are present, their exact matches must identify the same member. Confirm the intended Square Customer is attached to the sale before taking payment. Perkstar does not guess the buyer of an anonymous sale. Perkstar reads the completed Square payment, follows the location's programme route, credits the existing member once and queues their Wallet pass update. ### Optional Wallet QR attachment On a tested compatible device, staff can replace the normal customer search with one Wallet QR scan. The business must first enable Wallet-card identification, and that customer must have given current consent. In the Square checkout, open **Review sale → Add customer → scan icon**. Scan the QR code on the customer's Perkstar Wallet pass and confirm the correct Square Customer is attached before payment. Perkstar either reused one complete exact match or, only if none existed, created the profile. The payment follows the same customer-attributed earning path as a customer attached through Square's standard search. Wallet QR compatibility depends on the Square app and device. Terminal or Register running Square Point of Sale needs both **Scan customers using device camera** and **Show Add customer button during checkout** enabled. Attaching a customer only after checkout is not sufficient for Perkstar earning. Keep Square for Retail or Restaurants current. Test a Handheld or physical scanner against a QR displayed on a phone before relying on it; otherwise use the standard Square customer search. A customer must already belong to the routed Perkstar programme. An anonymous payment does not earn. The optional Wallet QR path does not change the payment boundary: an unrelated attached Square customer who does not match an existing Perkstar member is not enrolled, and the unmatched contact is not retained. ## How earning is calculated | Programme | Square payment result | | - | - | | Ordinary Stamp | One stamp for the completed customer-attributed payment | | Spend-based Stamp | Whole thresholds met × stamps configured per threshold | | Visit-based Stamp | The configured stamps per visit | | Spend-based Points | The configured points rate applied to the paid amount | | Visit-based Points | The configured points per visit | | Cashback | The active tier's percentage applied to the paid amount | The Square location either inherits the merchant's explicit default programme, uses its configured override, or deliberately pauses loyalty. Payment and webhook redelivery are idempotent, so the same completed payment cannot credit twice. ### Amount, timing and limits * Spend earning uses Square's `Payment.amount_money`, excluding the separately reported staff tip. It is not a pre-tax subtotal: Perkstar does not inspect individual products, tax lines or category exclusions. See Square's [Payment definition](https://developer.squareup.com/reference/square/objects/Payment). * Square and the Perkstar business must use the same currency. There is no currency conversion. Spend-points rates include the programme's configured spend unit and are rounded to two decimal places; spend-stamp thresholds are rounded down. Cashback is stored in whole minor currency units. * The earning unit is a **payment**, not an order or a calendar-day visit. Split-tender payments can produce more than one visit award; spend-stamp thresholds are evaluated separately for each payment. Do not promote one-award-per-basket or combined split-tender thresholds. * Processing is asynchronous: Square notifications are persisted, then the background worker and Wallet updates run. A Connected badge is not proof of a sale being credited. Offline sales cannot earn before Square receives the payment and Perkstar processes it. * Cancelled, failed, zero-value and anonymous payments do not earn. This integration follows payment completion, not appointment attendance or no-show status. It does not import historical sales from before installation. Programme rewards, daily stamp limits and applicable promotion rules remain Perkstar rules. Confirm the exact merchant programme, expected amount and reward threshold in the final test; do not infer them from the Square basket. ## Redeem a reward Redemption is completed in Perkstar. **Square Loyalty is not required**, and rewards are not copied into Square. Choose either of these two workflows; do not redeem the same reward through both. ### Option 1: the customer redeems from their pass The customer opens their Apple Wallet or Google Wallet pass details and chooses **Available rewards → Redeem**, or opens **My Account** and selects an available reward. They need an internet connection. Wait until staff are ready to honour the reward; simply showing an available reward is not a redemption. The customer selects the reward and the correct location if prompted, then slides to redeem. Perkstar validates eligibility, records the redemption and consumes the relevant reward or points. Wait for the live **Redeemed** confirmation; an error or pending screen is not confirmation. Staff check the business, reward and live countdown on the customer's screen, then apply the agreed complimentary item or discount in Square using their normal till procedure. The fresh confirmation lasts three minutes. A screenshot, an available-reward screen or an expired confirmation must not be accepted as a fresh redemption. This is customer-led redemption: staff do not need to open Perkstar Scanner for the supported reward. Staff still verify and fulfil it; Perkstar does **not automatically apply a Square discount** or link the redemption to a Square basket. The live screen is a staff check, not Square payment validation. ### Which Square-earned rewards can customers redeem themselves? | Perkstar reward | From the pass | | - | - | | Stamp card | Available, unexpired stamp reward vouchers, including eligible bonus rewards | | Points card using **Reward tiers** | A configured reward tier the customer's available points cover | | Points status-tier benefit or a separately granted offer | When shown as available and its programme rules allow it | | Points redeemed as a cash amount | Staff-assisted redemption; the pass does not let customers choose a monetary debit | | Cashback balance | Staff-assisted redemption; the pass does not let customers spend the cashback balance | Self-redemption uses the existing card and reward configuration; there is no Square-side self-redemption switch. The programme and enrolment must be active, and the reward must be available under its expiry, location and usage rules. Other Perkstar card types can have their own pass-redemption options, but that does not make them eligible for Square payment earning. Sliding to redeem consumes the reward in Perkstar immediately; it is not a reservation awaiting Square checkout. Closing the screen or letting the three-minute confirmation expire does not restore it. If checkout is cancelled, the confirmation expires before service, or a staff member is unsure whether it was already honoured, check the customer's Perkstar activity and resolve it with an authorised team member. Do not redeem again or apply a second discount. A Square refund corrects the supported earning from that payment; it does not automatically restore a separately redeemed Perkstar reward. ### Option 2: staff redeem using Perkstar Scanner The customer presents their Apple Wallet or Google Wallet pass. Staff scan it with Perkstar Scanner and confirm the correct member. Choose the available reward and complete the redemption. Wait for Perkstar to confirm it so the member's balance and audit trail remain authoritative. Add the corresponding complimentary item or discount in Square using the business's normal till procedure, then complete checkout. Do not create a parallel reward or loyalty balance in Square. Perkstar is the source of truth, and Square is the till where staff apply the matching item or discount after a confirmed Perkstar redemption. ## Customer matching and privacy For optional scan setup, current customer consent is required before Perkstar searches the connected Square directory, creates or links a profile, or publishes a reference. For a consenting customer, it exact-searches by stable reference, email and available phone without importing the directory. A unique existing customer can be linked; only if none exists may Perkstar create a profile from the member's name and contact details. Perkstar writes the stable Wallet scan value only into an empty `reference_id`, preserves every foreign value, and later releases only a value it can prove it owns. The customer can change this choice by opening the customer-account link on the back of their Wallet pass, then choosing **Preferences → Square customer identification**. For an ordinary attributed payment, Perkstar still reads only the attached Square customer. Its email address or phone number is transient matching input for an existing Perkstar member. A successful match creates an opaque identity link scoped to that Square merchant and installation. Contact details from an unmatched Square profile are discarded and are not used for marketing. If exact email and phone evidence points to different Perkstar members, neither field silently outranks the other. The payment awards nothing and remains queued for a safe retry while Perkstar opens a merchant-visible **Customer match** case. Correct the duplicate or member contact details; do not manually adjust a balance while the case is open. The case summary and support link contain only the safe operational wording and Perkstar case ID, not customer contact details or Square identifiers. For corrections and delayed events, continue to [Refunds and troubleshooting](/integrations/square/refunds-troubleshooting). # Square Source: https://developers.perkstar.co.uk/integrations/square/index Connect Square to Perkstar for customer-attributed earning, location-aware programme routing and matched refund corrections. Square Use completed Square payments to reward customers who have already joined a Perkstar programme. Staff attach the existing Square Customer before payment with Square's normal customer search. On a tested compatible device, the business can also enable optional Wallet QR identification so staff use **Review sale → Add customer → scan icon** instead. Perkstar applies the routed programme's earning rule and updates the member's Wallet pass. Customers can redeem eligible rewards themselves from their pass and show staff the live confirmation, or staff can use Perkstar Scanner. Staff then apply the matching item or discount in Square; it is not applied automatically. See the [redemption options and supported rewards](/integrations/square/earning-redemption#redeem-a-reward). Square is a **production beta** available to eligible Scale businesses through Perkstar's direct installer. The integration is not currently listed in the Square App Marketplace, but a Marketplace listing is not required to connect or use it. A business can start Square earning with valid programme routing and Square's normal customer search. Optional Wallet QR device acceptance and the separate Perkstar redemption workflow are not prerequisites for connecting or earning. On a tested compatible device, identify a consenting member with one Wallet QR scan. Exact matching, consented profile creation and reference ownership all fail closed. Route the Square location to an eligible Stamp, Points or Cashback programme and credit a completed payment exactly once. Full and partial refunds against the original Square payment reverse the corresponding Perkstar credit safely. ## System boundaries Perkstar is the loyalty system of record. Square supplies merchant, location, completed-payment, refund and attached-customer signals. In the standard workflow, staff find and attach the Square Customer before payment; email or phone must exactly match an existing member of the routed Perkstar programme. If the business enables optional Wallet QR identification, current customer consent gates every Square search, link and reference publication. For a consenting customer, Perkstar may exact-match an existing Square Customer, create one from their name and contact details only if no match exists, and put that member's stable Wallet scan value in an otherwise empty Square Customer `reference_id`. **Square Loyalty is not required.** Perkstar never creates or updates Square payments, loyalty balances or rewards, and it does not request Square Loyalty permissions. Customer write access is used only for the optional identification flow described above. | Event | What Perkstar does | | - | - | | Staff finds and attaches a Square Customer | Uses the attached profile as transient matching input | | Staff scans a prepared Wallet QR on a tested device | Square finds and attaches the linked Square Customer | | Completed payment with an attached matched customer | Applies the selected programme's earning rule once | | Anonymous payment | Ignores it because no customer can be identified | | Attached customer who has not joined Perkstar | Discards the unmatched contact without retaining or enrolling it | | Full or partial refund | Reverses the supported share of the original Perkstar credit once | | Reward redemption | Records redemption in Perkstar; staff complete the matching till adjustment in Square | ## What you need * A Perkstar **Scale** plan or another plan that includes POS Connect. * Owner access or a team role with **Edit operations** in Perkstar. * Permission to approve apps for the intended Square production account. * At least one active, earn-ready Stamp, Points or Cashback programme. * Customers enrolled in Perkstar before the payment you want to reward. * For one-scan identification: an individual default programme with a QR code and required First name and Email fields. Connect safely, choose the default programme and review every location. Give staff the exact customer, payment and reward workflow. Reconcile corrections, diagnose missing credit and disconnect safely. ## Data use For payment earning, Perkstar reads the Square merchant and location profile, completed payments and refunds, and only the customer attached to a payment. Email or phone is used transiently to find an existing Perkstar member. If no member matches, the contact is not retained, enrolled or used for marketing. Optional Wallet-card identification does nothing in Square without current customer consent. For a consenting customer, it performs complete exact searches by the stable scan reference, email and, when available, phone. If the searches resolve to one Square Customer, Perkstar links that profile. If none resolves, Perkstar may create a Square Customer from first name, optional surname, email and optional phone. Perkstar writes the stable Wallet scan value only when `reference_id` is empty, never overwrites a value owned by the merchant or another system, and releases only a value for which it has durable ownership evidence. After a successful match, Perkstar stores an opaque Square customer link scoped to that merchant and connection. It also stores encrypted OAuth credentials, card and location routing, and the operational and loyalty records required to deduplicate earning and reconcile refunds. See [Set up Square](/integrations/square/setup) for the permissions and test procedure. Need help with a Square connection? Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the Perkstar business name, approximate payment or refund time, and Square location name. Never send an access token, raw webhook payload, payment-card data or customer contact details. # Square refunds and troubleshooting Source: https://developers.perkstar.co.uk/integrations/square/refunds-troubleshooting Reconcile full and partial Square refunds, diagnose missing earning and disconnect the Square integration safely. ## Refunds Process the refund in Square against the **original payment**. Completed full and partial refunds reverse the corresponding Perkstar credit. Partial refunds use the proportional share supported by the original award and rounding rules; combined corrections never reverse more than the original credit. Corrections are based on the original credited amount, not a fresh calculation using today's programme rules or a returned item's category. Points corrections round to two decimal places; stamps and cashback minor units round down until the cumulative refunded amount justifies the next unit. For example, half of a one-stamp payment can reverse zero stamps; a full refund reverses that stamp. Square refunds are payment-level: there is no item-by-item or tip-only refund allocation. Review those adjustments with support before promising an exact loyalty outcome. If the customer has already used the loyalty value, Perkstar does not force a negative balance. It records a case requiring review. A refund also does not undo a discount that staff already applied at the till. Check any earned or redeemed rewards as part of that review. Square may report a refund while its payment or refund is still changing state. Perkstar waits for a terminal completed record, handles out-of-order delivery, and uses recovery reconciliation for missed notifications. Repeated delivery of the same refund is safe. The five-minute recovery job discovers missed **refunds**. For payments, recovery relies on Square's webhook retries and Perkstar's durable inbox; there is no general automatic historical payment import. Contact support if a completed, attributed payment is still absent—do not manually add loyalty while a delayed payment may still be processed. Do not make a manual loyalty correction while a Square refund is pending or under review. That can duplicate the automatic reversal. Record the original payment, refund time and Square location, then check the integration page. ## Troubleshooting Confirm Square setup is complete, the explicit default programme is eligible, and the selling location is not paused or invalid. The payment must be completed and have a Square customer attached before payment. That profile must match an existing member of the routed Perkstar programme by email, phone, a previously established opaque link or the owned Wallet scan reference. Use **Review sale → Add customer → scan icon**, not the payment barcode screen. Confirm Wallet-card scanning is on, the default programme is an individual active QR programme, and First name and Email are required. If the connection predates customer write access, reconnect Square. On Square Terminal or Register running Square Point of Sale, open **Settings → Checkout → Customer Management** and enable both **Scan customers using device camera** and **Show Add customer button during checkout**. **Show Add customer button after checkout** is optional; after-checkout attachment alone is not sufficient for Perkstar earning. Keep Square for Retail or Restaurants current. Test a Handheld or physical scanner against an on-screen Wallet QR before relying on it. If the device cannot scan the member there, use Square's normal customer search to attach the matching Square Customer before payment. A conflicting exact match or non-empty foreign reference is left unchanged and appears as an attention item in Perkstar. Square identification is optional and requires that customer's explicit Square Customer Directory consent before any exact search, link, creation or Wallet-reference publication. The member can grant or withdraw it from the Perkstar join surface. To change it later, they open the customer-account link on the back of their Wallet pass, then choose **Preferences → Square customer identification**. Without consent, Perkstar leaves Square unchanged. OAuth alone does not start earning. Choose an eligible unrestricted default programme, review every Square location, and repair any incompatible override. A location-restricted programme also needs an allowed Perkstar reporting location linked to that Square location. Joining Square is not the same as joining Perkstar. Ask the customer to join the routed Perkstar programme first, use the same email or phone on both records, then attach the Square customer before a new payment. An earlier anonymous or unmatched payment is not credited retrospectively, and the unmatched contact is not retained. That is expected. Square Loyalty is not required or written. The customer can redeem an eligible reward from their pass and show staff the live confirmation, or staff can redeem using Perkstar Scanner. Staff then apply the corresponding item or discount in Square; it is not automatic. Follow the [redemption guide](/integrations/square/earning-redemption#redeem-a-reward) for eligibility, confirmation checks and cancelled-checkout handling. Confirm the refund was completed against the original Square payment. Allow the terminal update and recovery reconciliation to finish before changing the member's balance manually. If an operational issue remains on the Square integration page, record the time and contact Perkstar support. If the seller is still listed with **Reconnect**, automatic token renewal failed or the current access expired. Reauthorise that same Square seller through the direct Perkstar installer. Perkstar replaces its credential in place and retains the saved default programme and location routes. If the connection was revoked or explicitly disconnected and the seller row was removed, start a fresh installation and configure the default programme and routes again. Square is available as a production beta through Perkstar's direct installer and is not currently listed in the Square App Marketplace. A Marketplace listing is not required. Confirm the organisation has Scale/POS Connect and that you are an owner or have **Edit operations**. If it still will not open, contact Perkstar support. ## Disconnect safely An organisation owner or team member with **Edit operations** can disconnect Square from **Settings → Integrations → Square**. New Square work stops immediately. Perkstar revokes the Square grant and removes encrypted credentials, merchant and location routing, opaque Square customer links, Square-sourced operational data and retained webhook payloads. Before local ownership evidence is purged, Perkstar attempts to clear only a Square Customer `reference_id` whose live value and durable ownership record both prove Perkstar set it. Foreign, merchant-edited and merely coincidental values are never removed. Square Customer profiles, including consent-created profiles, remain under the merchant's control. Existing de-identified Perkstar-authored loyalty balances and ledger entries remain so customers do not lose rewards already earned. A later reconnection is a fresh installation and requires the default programme and every location route to be configured again. Disconnect only after all expected refunds have settled. Once the Square payment link and credentials are removed, a later Square refund for a payment from the disconnected installation cannot be reversed automatically in Perkstar; contact support for a reviewed correction. If access is revoked in Square before disconnecting in Perkstar, Perkstar may also be unable to clear a Wallet QR reference it previously owned. The merchant can clear that stale `reference_id` from the Square Customer record or ask support for guidance. Email [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the Perkstar business name, approximate payment or refund time, and Square location name. Never send an access token, raw webhook body, payment-card data or customer contact details. # Set up Square Source: https://developers.perkstar.co.uk/integrations/square/setup Install the Square production beta, approve limited customer access, configure routing and enable optional Wallet-card identification. Complete setup before taking a customer test payment. Authorising Square is the first step; earning remains paused until the merchant has an explicit eligible default programme and its location routing is valid. Square is a **production beta** installed directly through Perkstar. Use Perkstar's direct installer; it is not currently listed in the Square App Marketplace, but a Marketplace listing is not required to connect or use the integration. Direct-install readiness uses the standard Square customer-search path: connect, finish programme and location routing, then complete matched-payment and refund checks. Optional Wallet QR device acceptance and a Perkstar reward redemption are not prerequisites for Square earning. ## Before you connect * Use the **Scale** plan or another plan that includes **POS Connect**. * Sign in as the organisation owner or a team member with **Edit operations**. * Be authorised to approve apps for the intended Square production account. * Prepare at least one active, unarchived, earn-ready Perkstar programme. * Ask a test customer to join that Perkstar programme before the test sale. * To use one-scan identification, make the default programme individual, use a QR barcode, and require First name and Email on its sign-up form. ### Eligible programmes | Programme | Eligible earning rule | | - | - | | Stamp | Ordinary Stamp, spend-based or visit-based earning with a valid rate | | Points | Spend-based or visit-based automatic earning with a positive rate | | Cashback | A configured first tier with a positive cashback percentage | Discount, Multipass, Membership, Coupon, Gift and Ticket cards cannot receive Square payment earning. A programme restricted to selected Perkstar locations cannot be the global default; route it only from a Square location linked to one of its allowed Perkstar locations. ## Connect the merchant You can also find Square from **Integrations → Marketplace** in Perkstar's navigation. On a phone, open the menu first. Search for **Square**, open its details and choose **Setup**. After connecting, use **Integrations → My integrations** to return to management. This is Perkstar's integration catalogue, not a claim that the app is listed in Square's App Marketplace. [Connect Square](https://dashboard.perkstar.co.uk/install/square), then sign in or create your Perkstar account. Select the eligible Scale organisation you want to connect if asked. Confirm the merchant you intend to connect and read how customer matching, storage and disconnect work. Choose **Continue to Square** only if you are authorised for that Square business. Sign in to the correct Square production account and approve `MERCHANT_PROFILE_READ`, `CUSTOMERS_READ`, `CUSTOMERS_WRITE` and `PAYMENTS_READ`. Customer write access supports optional Wallet-card identification only. Perkstar does not request payment write or Square Loyalty permissions. Back in Perkstar, check the Square business name, merchant identifier, country and currency. If the wrong merchant was authorised, disconnect it before configuring or taking a test payment. ## Choose the programme and locations Open **Settings → Integrations → Square** and select the programme that should receive payments by default. No organisation-primary or first-card fallback is used. Each location can inherit the default programme, use another eligible programme, or pause loyalty. Do not leave an active selling location in an invalid route. Link the Square location to the corresponding Perkstar location for reporting. This link is required before a location-restricted programme can be selected as that Square location's override. The Square page reports setup as incomplete while the default programme or any location route is ineligible. Correct every warning before testing. ## Attach the customer before payment The standard workflow does not require Wallet QR identification. Staff use Square's normal customer search and attach the existing Square Customer before payment. The customer must already belong to the routed Perkstar programme, and the attached Square profile's email address or phone number must exactly match that member. When both fields are supplied, every exact match must identify the same member. If email and phone point to different members, Perkstar awards nothing, keeps the payment queued for retry and opens a merchant-visible **Customer match** case until the duplicate or contact data is corrected. Anonymous or unmatched payments do not earn. ## Enable optional Wallet QR identification This optional feature lets Square identify a consenting Perkstar member from the QR code already displayed on their Apple Wallet or Google Wallet pass. Existing Square connections that do not include `CUSTOMERS_WRITE` must reconnect before the feature can be enabled; ordinary attached-customer earning remains available while it is off. Use an active, unarchived individual programme. Select **QR** as its barcode format and make **First name** and **Email** required on the sign-up form. In **Settings → Integrations → Square**, review the matching, creation and reference-ownership acknowledgement, then choose **Enable scanning**. Perkstar offers optional consent on the join surface. To change the choice later, the customer opens the customer-account link on the back of their Wallet pass, then chooses **Preferences → Square customer identification**. Current consent is required before any Square directory search, link or Wallet-reference publication. For a consenting customer, Perkstar exact-matches an existing Square Customer or, only if none exists, may create one from their first name, optional surname, email and optional phone. In Square, open **Review sale → Add customer → scan icon**, scan a test member's Wallet QR and confirm the correct Square Customer is attached before payment. Follow the device checklist below. ### Square device and app checklist | Square setup | Required preparation | | - | - | | Square Point of Sale on Terminal or Register | Open **Settings → Checkout → Customer Management**. Enable **Scan customers using device camera** and **Show Add customer button during checkout**. **Show Add customer button after checkout** is optional; after-checkout attachment alone is not sufficient for Perkstar earning. Attach the customer before payment. | | Square for Retail or Square for Restaurants | QR and barcode customer scanning is enabled automatically. Keep the app and device current, then test an on-screen Wallet QR on every device. | | Square Handheld or a physical scanner | Compatibility depends on the installed Square app and hardware. Enable any **Scanning for screens** option and test the exact device. Do not promise Wallet QR customer attachment until that test passes. | Square's current instructions are in its [customer QR and barcode scanning guide](https://squareup.com/help/gb/en/article/7387-identify-customers-at-your-counter-with-qr-codes). A physical scanner must be able to read a QR code displayed on a phone. If Wallet QR scanning is unavailable, staff use Square's normal customer search to attach the matching Square Customer by email or phone before payment. ### Safe matching and reference ownership * Without current Square-directory consent, Perkstar does not search, link or publish a Wallet reference. * For a consenting customer, Perkstar exhausts exact searches by the stable Wallet reference, email and, when available, phone. Conflicting or incomplete results are left unchanged for review. * A unique existing Square Customer can be reused. Only if no exact match exists may Perkstar create a profile from the disclosed fields. * Perkstar writes only the enrolment's stable `posBarcodeValue` into an empty Square Customer `reference_id`. * A non-empty `reference_id` is never overwritten, even if it resembles a Perkstar value without recorded ownership. * Turning the feature off, customer withdrawal, erasure or Square disconnect releases only a live reference value that Perkstar can prove it owns. The merchant's Square Customer remains. ## Test before serving customers Use a synthetic member and record the expected result from the selected programme's exact earning rules. 1. Confirm the test customer has already joined the routed Perkstar programme. 2. Use Square's normal customer search to attach a Square Customer whose email or phone exactly matches the synthetic Perkstar member. 3. Complete a small payment and confirm the standard attached-customer path credits the expected stamps, points or cashback once and refreshes the Wallet pass. 4. Refund part of that original payment and confirm the supported proportional correction appears once. 5. Refund the remainder and confirm the total correction never exceeds the original award. 6. If the business enables optional Wallet QR identification, opt the synthetic member in, test either a unique existing Square Customer exact match or consented creation, then scan the Wallet QR on every supported device and confirm the intended Square Customer is attached before payment. Also test a Square Customer with a non-empty foreign `reference_id`; Perkstar must not overwrite it. 7. If optional Wallet QR identification was enabled, turn it off and confirm only proven Perkstar-owned references are cleared. 8. Before offering redemption, agree the actual priced reward item or discount and train staff on the chosen workflow: customer self-redemption from the pass for supported rewards, or Perkstar Scanner. Test one genuinely available reward, verify Perkstar's saved redemption and remaining balance, and check the matching Square item/discount and currency. Do not manually set a balance to manufacture a successful test or incur charges without permission. A pass redemption does not automatically discount Square. Continue with the [staff earning and redemption guide](/integrations/square/earning-redemption). # Stripe Connect Source: https://developers.perkstar.co.uk/integrations/stripe/index Connect the business payment account and check payout readiness. Connect the business's Stripe account for supported customer payments and payout readiness. This is separate from the Stripe subscription the business pays to Perkstar, and separate from [Resend sending](/integrations/resend). ## Connect 1. Open **Integrations → Stripe Connect → Connect** in the intended business. 2. Follow Stripe's hosted onboarding and confirm the legal business and payment account details. Complete any requirements Stripe requests. 3. Return to the Perkstar workspace and inspect account and payout readiness. 4. If onboarding remains incomplete, use the continuation action and complete the outstanding provider requirements. Do not create a duplicate payment account. ## Confirm it is ready Authorisation alone does not mean that charging or payouts are enabled. Review the provider's requirements and the intended paid-card or commerce setup. Use the supported test workflow before accepting real customer payments; do not charge a customer merely to check the integration. ## Ownership and recovery The business owns its Stripe account and is responsible for accurate onboarding information. Stripe controls its verification and payout requirements. Use the workspace management action to reopen the provider account when permitted. If a requirement cannot be resolved, contact support with the account and visible error; never share banking credentials or secret keys in documentation or chat. # SumUp POS Custom Loyalty Source: https://developers.perkstar.co.uk/integrations/sumup-pos/index Connect a SumUp POS store, activate its gateway and verify loyalty at checkout. This integration uses **SumUp POS Custom Loyalty**. It is not a generic connection to every SumUp card reader or payment product. Access requires the POS Connect entitlement and release availability for the business. ## Connect the store 1. Open **Integrations → SumUp POS (Custom Loyalty) → Connect**. 2. Enter the store subdomain, optional display name and intended Perkstar loyalty programme, then choose **Create gateway URL**. 3. In SumUp POS Backoffice, open **Apps → Loyalty → Custom Loyalty Settings**. Paste the exact merchant gateway URL, name the connection Perkstar, enable it and save. 4. Copy the **Verification Token** displayed by SumUp POS back into the Perkstar workspace, then choose **Activate SumUp POS**. The gateway stays locked until activation. Treat the token as a secret. ## Verify checkout Use a controlled customer and scan their Wallet QR code. Check that the intended programme and available rewards appear, then verify one completed sale against its Perkstar transaction. Where product rewards are used, configure eligible product SKUs and maximum product value before redemption. Do not assume a displayed reward was settled until the completed-sale record confirms it. ## Recover safely Retain the original sale reference when investigating retries. A repeated callback must not grant the same reward twice. Check the store subdomain, programme mapping and verification token before replacing a connection. Changing the programme can affect future checkout eligibility and should be deliberate. Disconnect through **Manage**, and remove or disable the corresponding Custom Loyalty configuration in SumUp POS when retiring it. See the [POS safety walkthrough](/guides/pos) for identity and duplicate handling. # Sunmi Source: https://developers.perkstar.co.uk/integrations/sunmi/index Availability and next steps for Sunmi. **No self-service installation.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Connect Sunmi Cloud locations for sales polling when the production connector is released. This reference covers an existing or restricted connection. It is not an invitation to start a new connection. ## What to do now Open **Perkstar → Integrations** and inspect Sunmi. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # TikTok Pixel Source: https://developers.perkstar.co.uk/integrations/tiktok-pixel/index Configure TikTok Pixel measurement for supported customer journeys. Send supported customer journey events to your business's TikTok Pixel account. This is measurement, not a loyalty balance source or proof that a message was delivered. ## Configure the connection 1. Select the intended business in **Perkstar → Integrations → TikTok Pixel → Connect**. 2. Enter the **Pixel ID** and **Events API token** from the property or data source you control in TikTok Events Manager. 3. Save in the integration workspace. These are business-level settings inherited by its cards; do not paste a different business's credentials into a card. 4. A saved-secret hint means the secret is already stored. Leaving it untouched preserves it; entering a replacement deliberately updates it. ## Check an event Use a controlled test customer and a supported enrolment or loyalty journey with the required recorded marketing consent. Inspect the matching event in TikTok Events Manager. The implementation requires both the identifier and secret, plus the applicable consent, before firing these events. A saved identifier alone is not a completed verification. ## Troubleshooting and ownership Check the correct business, identifier, saved secret and test customer's consent. Provider reporting can differ from Perkstar transaction totals; attribution events are not the accounting record. Do not remove consent requirements to make a test appear. Keep secrets private and rotate them through the provider when necessary. Use the available workspace controls to remove the configuration when retiring it, then confirm with a controlled test that no new event is generated. See [security and privacy](/fundamentals/security-privacy). # Toast Source: https://developers.perkstar.co.uk/integrations/toast/index Availability and next steps for Toast. **No self-service installation.** Reviewed 13 September 2026. The status shown in the intended business's dashboard is authoritative for that account. Connect Toast sales and customer activity when the production integration is released. This reference covers an existing or restricted connection. It is not an invitation to start a new connection. ## What to do now Open **Perkstar → Integrations** and inspect Toast. If it says **Coming soon** or **Unavailable**, do not use an old setup URL or grant provider credentials to work around it. Documentation and a provider's developer portal do not themselves grant access to a Perkstar connector. If you already have an approved connection, use **My integrations → Manage** where available. Keep the original provider account and transaction references when asking support about a failure. Do not disconnect a working installation merely to test whether you can reconnect it. ## Discuss compatibility with support Provide the business account number, provider product/version, country, relevant store or location, and the loyalty workflow you need. Do not share passwords, API keys or customer lists. Ask support to confirm both access and an appropriate controlled test before relying on this connection for customer transactions. For a bespoke connection, start with the [POS guide](/guides/pos) and [API availability](/support/api-availability). A custom integration is a separate implementation, not a way to enable an unreleased native connector. # Zapier data and security Source: https://developers.perkstar.co.uk/integrations/zapier/data-security Understand OAuth access, customer-data flow, consent, retention, deletion, and operational safeguards for Perkstar Zaps. Connecting Zapier creates a new data flow chosen by the Perkstar business. The business decides which Zap runs, which fields are mapped, which destination apps receive them, and how long those destinations retain them. This page explains product behaviour and implementation responsibilities. It is not legal advice and does not replace the Perkstar [Privacy Notice](https://dashboard.perkstar.co.uk/privacy), [Data Processing Agreement](https://dashboard.perkstar.co.uk/dpa), [Terms of Service](https://dashboard.perkstar.co.uk/terms), Zapier's terms, or the business's own privacy review. ## Connection security Users approve Perkstar's hosted OAuth flow. The official connection never asks them to paste a Perkstar API key into a Zap field. Every credential resolves to one Perkstar organisation, and API resources are checked against that tenant boundary. The consent screen describes the access used by the configured triggers, actions, searches, and card selector. Perkstar still enforces every scope. The connection can be revoked. Revocation stops future API access but does not erase Zap history or copies already sent to another app. The prepared OAuth grant uses Authorization Code flow with required S256 PKCE, one-hour access tokens, and single-use rotating refresh tokens. Perkstar revokes the grant if an already-rotated refresh token is replayed. Each instant trigger also receives a per-subscription signing secret; the official app verifies the exact callback bytes and a five-minute HMAC timestamp before returning a Zap record. ## Requested access | OAuth scope | Used for | | - | - | | `CUSTOMERS_READ` | Find customers and resolve customer state needed by supported steps. | | `CUSTOMERS_WRITE` | Create or update a customer. | | `ENROLLMENTS_READ` | Find an enrolment, balance, status, or available Wallet links. | | `CARDS_READ` | Load active cards into selectors and validate card-aware steps. | | `EVENTS_READ` | Read the bounded recent event feed used to provide real trigger samples. | | `WEBHOOKS_WRITE` | Create, configure, and delete app-owned event subscriptions as Zaps are enabled or disabled. | | `MARKETPLACE` | Enrol a customer, record loyalty activity, and reverse an eligible transaction through the marketplace-safe endpoints. | | `PUSHES_WRITE` | Send a Wallet push through the explicit action. | The Zapier OAuth application cannot use these permissions to inspect or mutate webhook endpoints created by a different OAuth application or user. Perkstar also enforces tenant, plan, account-state, consent, card-type, and rate-limit checks after the scope check. ## Data the app can process | Feature | Potential Perkstar data | Why it is used | | - | - | - | | Instant triggers | Event ID/type/time, organisation ID, and the event-specific customer, card, enrolment, loyalty, purchase, membership, engagement, or booking fields | Start the selected Zap and provide its mapping fields. | | Find Customer | Customer ID/number, contact and profile fields, consent flags, external reference, and lifecycle timestamps | Match the intended customer and return current state. | | Find Enrolment or Pass | Customer/card IDs, status, balance/activity values, and available Wallet install URLs | Find the current programme relationship or pass link. | | Customer actions | The identity, profile, consent, and external-reference fields mapped by the user | Create or update the intended customer. | | Loyalty actions | Customer identifiers, card, amount/delta, stable transaction reference, note, and selected metadata | Enrol, record one compatible activity, or reverse the original transaction. | | Wallet push | Enrolment ID, message, resolved merge fields, and delivery result | Send a business-authored message to eligible Wallet passes. | The exact fields for each event are in the [webhook event catalogue](/reference/webhook-events). Perkstar does not add customer email, name, or phone to every trigger merely to make mapping convenient. Use a search only when the workflow needs current profile data and is authorised to copy it. ## Responsibility model ```mermaid theme={null} flowchart LR Customer["Cardholder"] --> Business["Business using Perkstar\nNormally the controller"] Business --> Perkstar["Perkstar\nNormally a processor"] Business --> Zapier["Zapier and enabled Zap apps\nChosen by the business"] Perkstar --> Zapier Zapier --> Destination["Destination app"] ``` The business is responsible for determining its role and lawful purpose for each destination, configuring access, giving required notices, and honouring access, correction, deletion, objection, and consent rights across all copies. Perkstar cannot govern a later Zap step after the data leaves Perkstar. ## Consent and messaging * A loyalty enrolment does not automatically grant email, SMS, advertising, or push-marketing consent. * Treat Perkstar consent fields as purpose-specific state, not blanket permission for every Zap destination. * Keep the source, wording, time, and lawful basis needed to support any consent assertion written from another app. * **Send Wallet Push** enforces push-marketing consent. A `403` is a safety outcome, not an error to route around. * Never place payment-card data, passwords, health data, or other sensitive free text in a loyalty note, push message, Zap field, or support request. ## Minimise and retain deliberately 1. Map only fields the next step needs. 2. Use opaque Perkstar IDs instead of copying a full profile where possible. 3. Limit who can edit the Zap and view Zap history. 4. Configure destination retention and logs; do not assume turning off the Zap deletes historical tasks. 5. Avoid broad chat-channel messages containing contact details or feedback text. 6. Redact customer payloads, OAuth tokens, unique hook target URLs, and Wallet URLs from screenshots and support messages. ## Disconnect, deletion, and rights requests Turning off a Zap stops future runs and deletes its corresponding app-managed Perkstar instant-trigger subscription. Re-enabling the trigger creates a fresh subscription and secret. Revoking the connected account stops future authorised API calls and pauses its remaining owned subscriptions. None of those actions automatically delete: * completed Zap runs in Zap history; * records created in a CRM, spreadsheet, chat tool, or other destination; * source records that another app still controls; or * Perkstar records the business is otherwise entitled or required to retain. For a rights request, locate data by Perkstar ID and any stable external reference, then apply the required export, correction, suppression, or deletion in Perkstar, Zapier, and each destination. Test this process before a live Zap copies customer data. ## Operational review * [ ] The Zap owner, every connected app, and every person who can edit the Zap are documented. * [ ] The Zap uses the correct tenant and minimum necessary fields. * [ ] Consent and suppression behavior is tested. * [ ] Zap editors and Zap history viewers are restricted. * [ ] Stable references make customer and transaction writes retry-safe. * [ ] Revocation, trigger removal, and destination deletion are tested. * [ ] Rights requests and incidents have named owners. Report suspected credential exposure, unauthorised access, or a personal-data incident to [privacy@perkstar.co.uk](mailto:privacy@perkstar.co.uk). For an operational failure, follow [Zapier troubleshooting](/integrations/zapier/troubleshooting). # Zapier Source: https://developers.perkstar.co.uk/integrations/zapier/index Connect Perkstar to other business tools with instant loyalty triggers and safe, scoped actions. Zapier Connect Perkstar loyalty activity to the tools a business already uses. The public Beta catalogue contains 29 instant triggers, including Wallet installs, online card scans, per-enrolment expiry, lifecycle-group changes, referrals, transactions, redemptions, memberships, and bookings. Ten focused actions can find, create, or update customers, enrol them in a card, add stamps or visits, award points, record purchases, redeem a balance, run a flexible loyalty write, reverse a transaction, or send a consented Wallet push. The official Perkstar app is available in **public Beta**. Open the [Perkstar page in Zapier's App Directory](https://zapier.com/apps/perkstar/integrations) to start a Zap or connect an account. No invitation or Perkstar API key is required. Authorise one Perkstar business through OAuth. No API key is copied into a Zap or shared with another person. Choose from 29 named triggers backed by Perkstar's durable webhook events. Use 10 scoped actions, stable references, idempotent writes, and explicit consent checks in production workflows. ## Availability | Item | Current position | | - | - | | Zapier listing | [Public Beta in Zapier's App Directory](https://zapier.com/apps/perkstar/integrations); no invitation needed | | Perkstar plan | Growth, Scale, Enterprise, or Franchise | | Connection | Perkstar OAuth; one Perkstar business per connected account | | Permissions | A Perkstar owner or authorised team member who can connect integrations | | Triggers | 29 named instant webhook triggers; no customer-list or transaction-list polling | | Actions and searches | 10 visible actions, two searches, and two Search-or-Create relationships | Public Beta access does not remove Perkstar's account and plan requirements. The person approving OAuth must already be able to access the intended Perkstar business. Zapier's public listing does not create a Perkstar business or add a person to an existing Perkstar team. ## What stays authoritative Perkstar remains the system of record for customers, enrolments, Wallet passes, loyalty balances, rewards, and outbound events. Zapier coordinates the workflow and keeps its own Zap configuration and Zap history. | Direction | What happens | | - | - | | Perkstar → Zapier | A selected Perkstar event starts a Zap with the event's documented fields. | | Zapier → Perkstar | A Zap calls a supported public v1 operation using the connected business's OAuth grant. | | Zapier → another app | The Zap sends only the fields the business maps into that step. | | Another app → Perkstar | The Zap validates and writes only the fields accepted by the selected Perkstar action. | Perkstar does not inspect or control later steps in a Zap. The business is responsible for the destination app, field mapping, lawful purpose, retention, and deletion of any copied customer data. Read [Data and security](/integrations/zapier/data-security) before using personal data or marketing actions. ## Start here Open the public listing, connect the correct Perkstar business, and test the OAuth grant. See all 29 triggers, 10 actions, two searches, required inputs, and important boundaries. Learn how subscriptions, retries, duplicate protection, testing, and replay work. Diagnose connection, sample-data, trigger, action, rate-limit, and consent failures without exposing a secret. For a problem in a Zap workflow, start with [Zapier Support](https://zapier.com/app/get-help). Zapier receives the run context, handles first-line troubleshooting, and sends Perkstar an actionable report when the Perkstar step needs our help. Contact [support@perkstar.co.uk](mailto:support@perkstar.co.uk) directly for a Perkstar account, plan, business-selection, or OAuth-consent problem. Never send either team an OAuth token, webhook target URL, or unredacted customer payload. # Zapier recipes Source: https://developers.perkstar.co.uk/integrations/zapier/recipes Build reliable Perkstar Zaps for customer onboarding, loyalty activity, operations, and consented messaging. These workflow patterns use the [public Perkstar app on Zapier](https://zapier.com/apps/perkstar/integrations). They are guided build recipes rather than one-click templates: choose the named Perkstar steps, test with controlled records, and keep the business's consent and retention rules in every destination app. ## Add a new member to a CRM or sheet **Trigger:** New Customer Enrolment **Then:** Find Customer → create or update the record in the destination Use the trigger's `enrollmentId`, `customerId` when present, `cardId`, `source`, and `occurredAt` as durable context. Run **Find Customer** only when the destination genuinely needs current profile fields; choose **Customer ID** and map the trigger's `customerId` when it is available. Joining a loyalty card is not blanket consent for email, SMS, advertising, or another app's marketing list. Map a purpose-specific consent field only when the business has auditable evidence for that destination and channel. ## Enrol an external lead and return available Wallet links **Trigger:** A qualified lead or checkout in another app **Action:** Enrol Customer in a Card **Then:** Send the returned Apple or Google Wallet URL through an appropriate transactional channel 1. Use a stable external customer reference from the source app. 2. Select the intended Perkstar card explicitly. 3. Map only the identity fields needed to find or create the customer. 4. Store the returned `customer.id` and `enrollment.id` in the source system. 5. If Wallet links are initially unavailable, use **Find Enrolment or Pass** later instead of constructing a Wallet URL yourself. ## Record a purchase exactly once **Trigger:** A paid or completed order in the commerce/POS app **Action:** Add Stamp or Visit, Award Points, or Record Purchase Map the source order or payment ID into the action's Source ID field. Perkstar automatically adds the Zapier action/activity namespace. Add your own source or store prefix when several stores can emit the same numeric value, for example: ```text theme={null} shopify:store-12:order:94721 ``` Choose the focused action that matches the selected card. Use **Record Purchase** for cashback or discount cards and map the integer minor-unit total; use **Add Stamp or Visit** or **Award Points** when the source already knows the exact balance change. Every action requires a Perkstar card and stable source activity/order ID. Use **Record Loyalty Activity** only when one Zap genuinely needs to select the activity type dynamically. Do not generate a new external transaction ID when Zapier retries a failed task. A stable source ID is what prevents a delayed or repeated order event from crediting loyalty twice. ## Reverse a refunded purchase **Trigger:** A completed refund in the source app **Action:** Reverse Loyalty Transaction Prefer the original Perkstar transaction ID saved by the earn Zap. If only the source order/payment ID is available, choose **Original Source Transaction ID**, select the exact Perkstar action that recorded it, and map the unchanged source ID. You can instead map the original action's exact returned External Transaction ID. Perkstar writes a compensating ledger row and returns an existing reversal if the same original was already reversed. Partial-refund business rules differ by integration. Agree the policy before turning the Zap on; the action does not infer a proportional reversal from an arbitrary source payload. ## Notify a team about a loyalty event **Trigger:** Reward Redeemed, Loyalty Tier Changed, Feedback Submitted, or another named event **Then:** Send a message to the team's approved operations channel Include the Perkstar event `id`, business timestamp, and opaque customer or enrolment ID needed to investigate. Avoid copying full contact details or free-text feedback into a broad channel. Link authorised staff back to the Perkstar dashboard when possible. ## Send a consented Wallet reminder **Trigger:** A deliberate business rule in another app **Action:** Find Enrolment or Pass → Send Wallet Push * Confirm the workflow has a clear customer purpose. * Target one current enrolment. * Map the source trigger's stable record ID into **Source Event ID**; keep it unchanged when Zapier retries. * Keep the message at or below 180 characters after merge-field expansion. * Expect `403` when push-marketing consent is absent. * Respect the shared three-minute per-card cooldown and `Retry-After` on `429`. * Do not loop a bulk list directly into rapid per-customer sends without an upstream rate and frequency cap. ## Production checklist * [ ] The Zap owner, connected Perkstar business, and destination owner are recorded. * [ ] Every write uses the narrowest action and an explicit card where needed. * [ ] Purchase flows use a stable permanent external transaction ID. * [ ] Duplicate, delayed, and out-of-order trigger tests are safe. * [ ] Consent and suppression behavior is tested with both allowed and blocked records. * [ ] `429`, non-retryable `4xx`, and destination-app failures are visible to an operator. * [ ] A disconnect, rights request, and downstream deletion procedure exists. For launch failures, use [Troubleshooting](/integrations/zapier/troubleshooting). # Connect Perkstar to Zapier Source: https://developers.perkstar.co.uk/integrations/zapier/setup Open the public Perkstar app, authorise one business with OAuth, and test a safe first Zap. The official Perkstar app is available in Zapier's public App Directory. The person connecting it signs in to Perkstar, chooses the intended business, reviews the requested access, and approves the connection. Zapier never asks the user to paste a Perkstar API key. Start from the [official Perkstar listing on Zapier](https://zapier.com/apps/perkstar/integrations). It is marked **Beta** and is available without an invitation. A page or similarly named app that asks for a raw Perkstar API key is not the official connection flow. ## Before you connect * The Perkstar business is on Growth, Scale, Enterprise, or Franchise. * You can sign in to both the intended Perkstar and Zapier accounts. * Your Perkstar role can connect integrations for the business. * At least one active loyalty card exists for card-based actions and filters. * You know which Zap owner, destination apps, and customer fields the workflow will use. One Zapier connection represents one Perkstar business. If you operate more than one business, create a separate connected account for each one. You can reuse the same connected account in multiple Zaps for that business; there is not a one-Zap-per-connection limit. ## Connect the account Open the [Perkstar App Directory page](https://zapier.com/apps/perkstar/integrations), sign in to the Zapier account that will own the workflow, and choose a Perkstar trigger or action. You can instead open Zapier's **App connections**, select **Add connection**, and search for **Perkstar**. Add a Perkstar trigger, action, or search and select **Sign in** when Zapier asks for a connected account. Zapier opens Perkstar's hosted authorisation page over HTTPS. Confirm the business name and account shown by Perkstar. If it is wrong, stop and switch account or organisation before approving. The resulting OAuth grant is tenant-scoped and cannot read or write another business. Read the plain-language permissions on the Perkstar consent screen. The app requests the access needed by its available triggers, actions, searches, and card selector. Perkstar returns a revocable OAuth grant to Zapier; no raw API key is displayed. Give the connected account a name that identifies the business, for example `Perkstar — North Street Coffee`. Run Zapier's connection test and confirm the returned business is the one you intended. The public Zapier listing gives access to the integration; it does not create a Perkstar login. If you are joining an existing business, accept that business's Perkstar team invitation first and then return to Zapier. If you do not yet use Perkstar, create the business account and eligible plan before authorising the connection. ## Build the first Zap Start with a reversible or read-only workflow before sending customer messages or changing loyalty balances. Pick one named Perkstar trigger, or use **Find Customer** / **Find Enrolment or Pass** to prove the connection without changing data. The full list is in the [catalogue](/integrations/zapier/triggers-actions). Card-aware steps load the active cards from the connected Perkstar business. Focused loyalty actions show only compatible programmes: Stamp/Multipass for Add Stamp or Visit, Points for Award Points, and Cashback/Discount for Record Purchase. Redeem Loyalty Balance supports Stamp, Points, Cashback, and Multipass balances; coupons, memberships, discounts, gift cards, and tickets use different flows. Select an explicit card when the business has several eligible programmes. Never paste a card name where a card ID is expected. Use an internal test customer whose data you are authorised to process. For an instant trigger, ask Zapier to test the trigger and perform the exact Perkstar event it is waiting for. For an action, verify the previewed inputs before running the test. Confirm Zapier received the expected fields and, for a write, confirm the Perkstar customer, enrolment, transaction, or push result. A successful Zap step is not proof that a later destination step used the correct field. Turn the Zap on for one card or low-risk workflow first. Monitor Zapier Task History and the relevant Perkstar records before widening the audience. When a workflow should continue after a search miss, use Zapier's explicit **Find or Create Customer** or **Find or Enrol Customer in a Card** option. For trigger enrichment, choose **Customer ID** in **Find Customer** and map the trigger's `customerId`; this avoids a second identity guess from email or phone. ## Connection lifecycle | Change | Effect | | - | - | | Turn a Zap off | Zapier stops the workflow and deletes its app-managed Perkstar instant-trigger subscription. Historical tasks remain under Zapier's retention settings. | | Remove an instant trigger | Zapier deletes the corresponding Perkstar webhook subscription. Re-enabling creates a fresh callback subscription and signing secret. | | Reconnect the account | Future steps use the renewed OAuth grant; stable subscription/action retries remain scoped to the same business grant. Test every enabled Zap afterwards. | | Revoke Perkstar access | API calls fail and owned instant subscriptions are paused until the account is reconnected or the Zap is recreated. | | Remove a destination app | Perkstar cannot remove data already copied into that app. Delete or retain it under the business's own policy. | To revoke the connection from Perkstar, open **Settings → Authorised apps** for the connected business and revoke Zapier. Then remove or reconnect the account in Zapier before re-enabling any affected Zaps. Read [Troubleshooting](/integrations/zapier/troubleshooting) before reconnecting an account used by several live Zaps, and read [Data and security](/integrations/zapier/data-security) before mapping personal data. ## Get support For a problem in a Zap workflow, start with [Zapier Support](https://zapier.com/app/get-help). That route includes the Zap and run context Zapier needs for first-line troubleshooting; Zapier will escalate an actionable Perkstar integration report to us when necessary. Contact [Perkstar Support](mailto:support@perkstar.co.uk) directly when the OAuth page shows the wrong Perkstar business or the issue concerns a Perkstar account, plan, team invitation, or consent screen. Before contacting support, keep the failed run in Zap history and note the step name, approximate UTC time, Zap run/task ID, and any Perkstar `X-Request-Id`. Redact customer data and never send passwords, OAuth tokens, refresh tokens, or webhook target URLs. # Triggers, actions, and searches Source: https://developers.perkstar.co.uk/integrations/zapier/triggers-actions The exact operations in the public Perkstar app for Zapier, including event names and safety boundaries. The public Beta catalogue contains 29 instant triggers, 10 visible actions, two searches, and two explicit Search-or-Create relationships. Zapier subscribes to one Perkstar webhook event when the Zap is enabled and deletes that app-managed subscription when the trigger is disabled or removed. Open [Perkstar in Zapier's App Directory](https://zapier.com/apps/perkstar/integrations) to use this catalogue without an invitation. The app is in public Beta, so event payloads can gain new optional fields; map only the fields your Zap needs. ## Instant triggers The integration defines one named Zapier trigger for each real business event below. The diagnostic `webhook.test` event is deliberately excluded from the Zapier catalogue. ### Customer lifecycle | Zapier trigger | Perkstar event | Fires when | | - | - | - | | New Customer Enrolment | `customer.enrolled` | A customer first joins a loyalty card. | | Customer Unenrolled | `customer.unenrolled` | Access to a card ends. | | Customer Anonymised | `customer.anonymized` | Perkstar removes the customer's direct identifiers. | | Customer Lifecycle Group Changed | `customer.group_changed` | A customer moves between Perkstar's six exclusive lifecycle groups. | The lifecycle-group trigger does not represent an operator-created saved segment. Perkstar stores a customer's first classification as a baseline and does not emit it, preventing a newly connected Zap from receiving every existing customer. ### Wallet, scanner, expiry, and referrals | Zapier trigger | Perkstar event | Fires when | | - | - | - | | Wallet Pass Installed | `wallet.installed` | Perkstar first observes an Apple or Google Wallet install; Google observation is periodic rather than immediate. | | Card Scanned | `card.scanned` | An online Perkstar Scanner lookup successfully resolves a customer card; offline cache-only lookups do not fire. | | Customer Card Expired | `card.expired` | One enrolment reaches its effective expiry; a later expiry after extension can produce another event. | | New Customer Referral | `referral.created` | One customer refers another customer to a Perkstar loyalty-card programme. | `referral.created` is customer-to-customer loyalty activity. It is not a merchant, agency, or partner-referral event. The first group-change or Google-install trigger in a business establishes a no-event baseline on the next completed periodic sweep. Tracking begins after that warm-up; Apple installs remain callback-driven, and post-subscription expiries retain their effective expiry time while waiting for projection. The five trigger records flatten these event fields for later Zap steps: | Trigger | Event-specific fields | | - | - | | Customer Lifecycle Group Changed | `customerId`, `previousGroup`, `currentGroup`, `occurredAt` | | Wallet Pass Installed | `walletPassId`, `enrollmentId`, `customerId`, `cardId`, `platform`, `detectionSource`, `installedAt`, `occurredAt` | | Card Scanned | `scanId`, `enrollmentId`, `customerId`, `cardId`, `credentialType`, nullable `walletPassId`, nullable `platform`, nullable `locationId`, `occurredAt` | | Customer Card Expired | `enrollmentId`, `customerId`, `cardId`, `cardType`, `expiresAt`, `expirySource`, `occurredAt` | | New Customer Referral | `referralId`, `cardId`, `referrerEnrollmentId`, `referrerCustomerId`, `referredEnrollmentId`, `referredCustomerId`, `status`, `bonusTiming`, nullable `creditedAt`, `occurredAt` | ### Loyalty activity | Zapier trigger | Perkstar event | Fires when | | - | - | - | | New Loyalty Transaction | `transaction.created` | A supported loyalty-ledger row commits, including a compensating reversal. | | Coupon Redeemed | `coupon.redeemed` | A coupon card is redeemed. | | Reward Redeemed | `reward.redeemed` | A reward, offer, voucher, or milestone is redeemed. | | Loyalty Tier Changed | `tier.changed` | A status, cashback, or discount tier changes. | ### Tickets, gifts, and multipasses | Zapier trigger | Perkstar event | Fires when | | - | - | - | | Ticket Purchased | `ticket.purchased` | Paid ticket fulfilment completes. | | Ticket Cancelled | `ticket.cancelled` | A ticket event is cancelled. | | Ticket Refunded | `ticket.refunded` | A ticket payment is refunded or lost to chargeback. | | Gift Card Purchased | `gift.purchased` | Paid gift fulfilment completes. | | Gift Card Redeemed | `gift.redeemed` | Value is spent from a gift card. | | Multipass Purchased | `multipass.purchased` | A multipass is purchased or topped up. | ### Memberships | Zapier trigger | Perkstar event | Fires when | | - | - | - | | Membership Purchased | `membership.purchased` | A recurring or one-off membership first activates. | | Membership Renewed | `membership.renewed` | A recurring membership advances to a new billing period. | | Membership Cancelled | `membership.cancelled` | A recurring membership becomes cancelled or incomplete-expired. | ### Engagement | Zapier trigger | Perkstar event | Fires when | | - | - | - | | Feedback Submitted | `feedback.submitted` | A customer submits card feedback. | | Automation Fired | `automation.fired` | A Perkstar automated-message firing is recorded. | | Broadcast Sent | `broadcast.sent` | A Wallet broadcast reaches terminal delivery processing. | ### Bookings | Zapier trigger | Perkstar event | Fires when | | - | - | - | | Booking Created | `booking.created` | A booking is created. | | Booking Confirmed | `booking.confirmed` | A booking moves to confirmed. | | Booking Attended | `booking.attended` | Attendance is recorded. | | Booking Marked as No-Show | `booking.no_show` | A booking is resolved as a no-show. | | Booking Cancelled | `booking.cancelled` | A booking is cancelled. | The official app accepts the event at its unique Zapier REST Hook URL and then exposes a mapping-friendly record: | Zapier field | Meaning | | - | - | | `id` | Unique event/delivery ID; automatic delivery retries retain it. | | `event_type` | Dotted Perkstar event name. | | `event_created_at` | Source event time as an ISO 8601 timestamp. | | `organization_id` | Connected Perkstar business ID. | | Event-specific fields | The raw `data` fields flattened onto the record, such as `customerId`, `cardId`, or `occurredAt`. | For booking events, the raw `data.id` is exposed as `resource_id` so it cannot replace the trigger's primary `id`. See the [webhook event catalogue](/reference/webhook-events) for required, optional, and nullable event fields. The app keeps documented optional mapping fields present with `null` when the live event omits them, but does not enrich every trigger with a customer profile. Add **Find Customer** only when the event carries a customer ID and the Zap needs current contact fields. ### Trigger options * **Card (Optional)** is available on every named trigger except **Customer Anonymised**, **Customer Lifecycle Group Changed**, and **Automation Fired**. Leaving it blank accepts the event from every card. * **Include Test Events** appears on **New Loyalty Transaction** and **Reward Redeemed**. It is off by default so test API activity cannot start live downstream steps; enable it only in a dedicated test Zap. ## Actions Non-idempotent write actions use deterministic idempotency keys; customer updates are naturally repeatable PATCHes. Loyalty activity and Wallet pushes require the source app's stable transaction or event ID; use a real record ID rather than a timestamp or random value. Perkstar automatically namespaces each loyalty source ID by Zapier action and activity type. Retrying the same action and source ID remains safe, while reusing an order ID for a different loyalty operation cannot replay the wrong transaction. References that would exceed the API's 180-character limit use a deterministic SHA-256 form. Every POST-based Zapier action checks the current OAuth credential before it looks for an earlier response. Refreshing the access token for the same Perkstar connection preserves retry protection, while a revoked connection is denied instead of replaying an earlier success. The four focused loyalty actions provide guided fields for common merchant jobs. **Record Loyalty Activity** remains available for workflows that need to choose the activity type dynamically. Each source transaction ID is permanently bound to its first canonical customer, card, operation, and amount. An exact Zapier retry returns the original result; reusing that ID with different inputs stops with a conflict instead of silently returning or changing the first transaction. All four focused loyalty actions and **Record Loyalty Activity** include **Create Customer If Missing**, which defaults **off**. Leave it off when the workflow should reward only existing members. Turn it on deliberately when a lookup miss should create the customer and enrol them in the selected card before applying the loyalty write. A missing or cross-business Customer ID is never treated as permission to create a replacement customer. | Zapier action | What it does | Important boundary | | - | - | - | | Create Customer | Creates a customer, or returns the existing customer when a matching `external_ref` is supplied. | Without `external_ref`, a duplicate email can return a conflict instead of overwriting a profile. | | Update Customer | Updates the mapped fields on one existing Perkstar customer. | Blank or omitted mappings must be reviewed carefully; this action does not anonymise or delete a customer. | | Enrol Customer in a Card | Finds a customer by Customer ID, email, phone, external reference, or pass barcode; can create a missing customer; and enrols them in the required active card. Returns available Apple/Google Wallet links. | An existing active pair is returned. An inactive or revoked pair halts for review rather than being silently reactivated; Wallet links can initially be `null`. | | Add Stamp or Visit | Adds a positive whole number of stamps or visits to an active Stamp or Multipass card. | Its selector shows only Stamp and Multipass cards, and a mapped incompatible Card ID is rejected. A stable Source Activity ID supplies permanent duplicate protection. | | Award Points | Adds a positive points amount, including up to two decimal places where the card permits it. | Its selector shows only active Points cards. The amount cannot exceed 100,000; a stable Source Points Award ID supplies permanent duplicate protection. | | Record Purchase | Records an integer minor-unit purchase amount on an active Cashback or Discount card. | Its selector shows only Cashback and Discount cards. The purchase amount must be positive; a stable Source Order or Payment ID supplies permanent duplicate protection. | | Redeem Loyalty Balance | Deducts a positive whole-number balance or prepaid visit from an active Stamp, Points, Cashback, or Multipass card without allowing the balance below zero. | Its selector excludes Coupon, Membership, Discount, Gift, and Ticket cards, which have separate or no balance-redemption flow. A mapped incompatible Card ID is rejected. | | Record Loyalty Activity | Finds or creates the customer and enrolment when allowed, then records one compatible Stamp, Redeem, Check-in, Discount, or Points activity through `/marketplace/accrue`. | The Card and Source Transaction ID are required. Card-type mismatches fail, and the source ID supplies permanent duplicate protection. | | Reverse Loyalty Transaction | Creates one compensating transaction for an eligible transaction previously recorded through Perkstar's marketplace API, found by Perkstar transaction ID, original source ID plus action, or exact external transaction ID. | A transaction can be reversed once. The action does not edit or delete the original ledger row. | | Send Wallet Push | Sends a plain-text message of up to 180 characters to one enrolment's eligible Wallet passes. | Enrolment ID and Source Event ID are required. Push-marketing consent and a three-minute per-card cooldown are enforced; success cannot guarantee device display. | ### Action inputs | Action | Required | Optional | | - | - | - | | Create Customer | At least one of Email Address, Phone Number, or External Reference | First/last name, date of birth, marketing/ad-tracking consent, Unique Request ID | | Update Customer | Customer ID and at least one profile or consent field to update | Profile and consent fields that are not changing may be omitted | | Enrol Customer in a Card | Find Customer By, Customer Lookup Value, Card | Create Customer If Missing (defaults on), first/last name for a new customer, Enrolment Source | | Add Stamp or Visit | Find Customer By, Customer Lookup Value, Card, Stamps or Visits to Add, Source Activity ID | Note, Create Customer If Missing (defaults off), first/last name | | Award Points | Find Customer By, Customer Lookup Value, Card, Points to Award, Source Points Award ID | Note, Create Customer If Missing (defaults off), first/last name | | Record Purchase | Find Customer By, Customer Lookup Value, Card, Purchase Amount (Minor Units), Source Order or Payment ID | Note, Create Customer If Missing (defaults off), first/last name | | Redeem Loyalty Balance | Find Customer By, Customer Lookup Value, Card, Balance to Redeem, Source Redemption ID | Note, Create Customer If Missing (defaults off), first/last name | | Record Loyalty Activity | Find Customer By, Customer Lookup Value, Card, Activity Type, Source Transaction ID | Purchase Amount (Minor Units), Balance Change, note, Create Customer If Missing (defaults off), first/last name | | Reverse Loyalty Transaction | Find Transaction By and Transaction Reference | Original Perkstar Action when using the original source ID; Reason | | Send Wallet Push | Enrolment or Pass, Message, Source Event ID | None | The loyalty action accepts the wire-level activity types supported by the public endpoint: `STAMP`, `REDEEM`, `CHECK_IN`, `DISCOUNT`, and `POINTS`. `DISCOUNT` requires a positive amount in integer minor units. `POINTS` requires either a balance change (up to two decimal places) or a positive purchase amount. The selected card's type determines which values are valid. **Send Wallet Push** supports `{firstName}`, `{lastName}`, `{balance}`, `{cardName}`, `{installLink}`, `{shareLink}`, and `{orgName}` merge fields. Map the originating trigger's stable `id` into **Source Event ID** so a retry of the same source event is collapsed within Perkstar's 24-hour idempotency window. ## Searches | Zapier search | Matching behavior | Result | | - | - | - | | Find Customer | Looks up by exact Customer ID, email, phone, external reference, or pass barcode/serial. | Matching current customer records, or a not-found result the Zap can branch on. | | Find Enrolment or Pass | Resolves Customer ID, email, phone, external reference, or pass barcode without creating records, then matches Card ID; status defaults to Active. | The same root result shape as Enrol Customer: nested customer and enrolment data plus available Wallet pass URLs. | ### Search-or-Create relationships Zapier exposes both relationships explicitly, so a workflow can branch on a search miss without constructing a custom API step: | Zapier option | Search | Create action | Result on no match | | - | - | - | - | | Find or Create Customer | Find Customer | Create Customer | Creates the customer from the mapped identity/profile fields. | | Find or Enrol Customer in a Card | Find Enrolment or Pass | Enrol Customer in a Card | Enrols the selected customer in the selected active card. | The enrolment pair still requires a customer and card. Repeatedly selecting the same customer/card pair returns the existing active enrolment rather than creating a duplicate. Perkstar never undoes an inactive or revoked status implicitly: if the Active search misses but the create step finds that status, the action halts with instructions to review the enrolment. The app uses hidden dynamic-field helpers that paginate through up to ten pages of 200 cards (2,000 total) before filtering. General selectors show every active card; Add Stamp or Visit shows only Stamp and Multipass cards, Award Points only Points cards, Record Purchase only Cashback and Discount cards, and Redeem Loyalty Balance only Stamp, Points, Cashback, and Multipass cards. These helpers are not advertised as standalone actions. A mapped Card ID is still checked when the focused action runs, so mapping an incompatible card does not bypass the selector. Searches return current API state, while a trigger contains the event snapshot produced at the time of the business change. If a Zap must preserve the exact event context, store the trigger values before running later searches. ## Behavior the app does not expose * No action edits card configuration, rewards, tiers, coupons, or orders. * No action bypasses Perkstar consent, plan, card-type, tenant, or rate-limit checks. * `webhook.test` is not a customer-facing Zapier trigger. * A trigger does not promise customer email, name, or phone unless that field is part of the documented event payload. * Searches do not scan another Perkstar business connected to the same Zapier account. # Zapier troubleshooting Source: https://developers.perkstar.co.uk/integrations/zapier/troubleshooting Diagnose public-app access, OAuth, instant triggers, actions, searches, rate limits, and consent failures. Start with Zap history and the connected Perkstar business. Record the step name, event or request time, status, and any Perkstar `X-Request-Id` before retrying. Never copy an OAuth token, unique hook target URL, or full customer payload into a support message. ## Connection and access Open the [official public Beta listing](https://zapier.com/apps/perkstar/integrations), confirm you are signed in to the intended Zapier account, and search for **Perkstar** rather than a similarly named app. You can also use **App connections → Add connection**. No invitation is required. If a managed Zapier workspace restricts apps, ask its administrator to allow Perkstar. The public listing does not create or join a Perkstar business. If you are an existing team member, accept the Perkstar team invitation sent to your exact email address and sign in with that account before reconnecting. Do not create a second business just to authorise Zapier. If you are a new customer, finish Perkstar account and plan setup first. Zapier is available to Growth, Scale, Enterprise, and Franchise businesses. Confirm the current Perkstar plan and that you are connecting the intended business. Free and Starter businesses must upgrade before connecting. Cancel instead of approving. Sign out or switch to the correct Perkstar organisation, then start the connection again. One connected account is tenant-scoped to one business. One connected account is scoped to one Perkstar business, but it can be reused across many Zaps. Add a separate Perkstar connection for each other business and give each connection a clear name. A Zapier account can hold multiple Perkstar connections. Reauthorise the Perkstar connected account in Zapier, then test every enabled Zap that uses it. If access was revoked in Perkstar, a new approval is required; retrying the old task does not restore the grant. ## Instant triggers Confirm the Zap uses the correct Perkstar business and named event. Start the Zapier test/listen step first, then perform that exact event. If a card filter is present, confirm the event belongs to the selected active card. The diagnostic `webhook.test` event does not satisfy a business-event trigger. Check that the Zap is published and enabled, the connected account is still authorised, and the expected Perkstar business event actually completed. Inspect Zap history. Perkstar keeps app-managed delivery attempts out of the custom-webhook dashboard so their callback URL and signing secret cannot be changed behind Zapier's back; quote the event time and ID to Perkstar support if Zap history is not enough. Automatic retries keep one logical delivery ID and should deduplicate. Confirm the runs have the same trigger `id`. Protect destination writes with the Perkstar ID or another stable source reference. This is allowed. Compare the event-specific `occurredAt` timestamp and the destination's current state. The exposed `event_created_at` field expresses that same source-event time in ISO 8601; the internal signing timestamp is the delivery-attempt time. Documented optional mapping fields can be `null` when they do not apply, and trigger bodies are not automatically enriched with a customer profile. Review the [event catalogue](/reference/webhook-events), guard optional mappings, and add **Find Customer** or **Find Enrolment or Pass** only when current state is appropriate. Creating a pass or opening its save link is not installation evidence. Apple normally reports installation through its device callback. Google is observed periodically; recently issued passes are eligible on the 15-minute projector, while object age, provider cadence, and projector backlog can extend the delay. Check the Zap and pass again after a later completed sweep rather than treating 15 minutes as an SLA. The trigger fires only for the first observed install of that pass. A business's first Google-install trigger uses its first check as a no-event baseline; tracking begins after that warm-up, so enable and test the Zap before distributing install links. **Card Scanned** covers successful online Perkstar Scanner lookups only. A lookup served solely from the scanner's offline cache never reaches the webhook boundary and does not fire this trigger. Dashboard searches and POS customer lookups are also excluded. The trigger reports movement between Perkstar's six exclusive lifecycle groups, not entry into or exit from an operator-created saved segment. A customer's first classification is stored as a baseline without an event, preventing a new Zap from replaying the entire customer base. For the first interested trigger in a business, allow one completed periodic sweep to establish that baseline before expecting later transitions. The event belongs to one enrolment and one effective expiry instant. If the enrolment is extended or reissued and later reaches a different expiry, another event is expected. Use `enrollmentId` plus `expiresAt` as the business identity when the destination needs its own duplicate protection. This trigger is customer-to-customer loyalty activity. It includes both the referrer's and referred customer's IDs, but it does not represent an agency, merchant, partner, or affiliate invitation. ## Searches and actions | Symptom | Likely cause | What to do | | - | - | - | | Find Customer returns no match | Wrong lookup type/value, cross-business Customer ID, email casing/format issue, or exact phone format differs | Prefer the trigger's Customer ID or a stable external reference/pass barcode; use the same phone format the source stores. | | Find Enrolment or Pass returns no Wallet URL | Pass issuance is still pending or that Wallet platform is not configured | Retry the search later; never construct an install URL. | | Find or Enrol reports a revoked/inactive pass | The customer/card pair already exists and Perkstar will not silently undo its status | Review and explicitly reactivate the enrolment in Perkstar before retrying; do not create a duplicate customer. | | A card is absent from a focused action | The card type is not valid for that action or the card is not active | Choose the matching action/card type; mapping an incompatible Card ID is rejected too. | | `400 ambiguous_default_card` | The business has several active cards and no card was selected | Select the intended card explicitly in the Zap step. | | `401` or connection error | OAuth grant is invalid, expired beyond recovery, or revoked | Reconnect the Perkstar account, then retest affected Zaps. | | `403` permission error | The OAuth grant lacks the required access or the operation is not allowed for the business | Reauthorise the official connection and confirm plan/role eligibility; do not substitute a raw API key. | | `403 push_marketing_consent_required` | The customer has not consented to marketing Wallet pushes | Stop the message. Obtain and record valid consent through an approved process before another marketing send. | | `404` | Customer, enrolment, card, or original transaction does not belong to the connected business or no longer exists | Check the connection and mapped opaque IDs; do not reuse an ID from another business. | | `409` creating a customer | A conflicting customer exists and the Zap did not use a stable `external_ref` upsert | Find the existing customer or provide the source system's stable external reference. | | `409 external_transaction_id_conflict` | A loyalty Source ID was reused with a different customer, card, operation, or amount | Keep the original inputs for a retry, or use the genuinely different source record's own stable ID. | | `409 webhook_subscription_limit_reached` | This OAuth connection owns 200 instant-trigger subscriptions, including paused rows from an interrupted cleanup | Turn off/remove unused instant triggers, confirm unsubscribe succeeds, then enable the new trigger again. | | `422` recording loyalty | Activity does not match the selected card type or the source reference belongs to the other environment | Correct the card/activity mapping; never hide the error by generating a new transaction reference. | | `429` | Credential rate limit or three-minute Wallet-push card cooldown | Let Zapier wait for `Retry-After`; reduce loops and burst frequency. | | `5xx` or network timeout | Temporary Perkstar or network failure | Retry the same logical task with the same stable identifiers; check [API status](/support/status). | ## Safe replay Before retrying or manually replaying a failed task: 1. Decide whether the earlier action may already have succeeded. 2. Keep the same source ID field value. Perkstar recreates the same action-specific external transaction ID, including its deterministic hash form when needed. 3. Fix a non-retryable validation, permission, or consent error first. 4. Retry from Zapier once and inspect the returned Perkstar record. 5. Replay once, then inspect the result before trying again. To reverse a Zapier loyalty write, prefer its returned **Perkstar Transaction ID**. If only the original source ID is available, select **Original Source Transaction ID** and the exact Perkstar action that recorded it. If mapping the returned **External Transaction ID**, map it exactly without removing the `zapier:` namespace. ## Ask for help For a problem in a Zap workflow, use [Zapier Support](https://zapier.com/app/get-help) first. That route preserves the Zap and run context for Zapier's first-line troubleshooting; Zapier will escalate an actionable Perkstar integration report to us when needed. Contact [Perkstar Support](mailto:support@perkstar.co.uk) directly for a Perkstar account, plan, team invitation, business-selection, or OAuth-consent problem. For a support request, keep the failed run in Zap history and include: * the Perkstar business name; * the Zapier trigger, action, or search name; * the approximate UTC time and Zap run/task ID; * the Perkstar `X-Request-Id`, event ID, or delivery ID when available; and * the status/code with secrets and personal fields removed. Do not delete the failed history before support has finished tracing it. Never send a password, OAuth token, refresh token, webhook target URL, or full customer payload. For suspected exposure or a personal-data incident, contact [privacy@perkstar.co.uk](mailto:privacy@perkstar.co.uk) immediately. # Instant triggers and webhooks Source: https://developers.perkstar.co.uk/integrations/zapier/webhooks Understand how Zapier subscribes to Perkstar events, handles retries, deduplicates deliveries, and manages hooks. Perkstar's named Zapier triggers use REST-hook subscriptions. When a Zap with a Perkstar trigger is enabled, Zapier registers its HTTPS callback for that one dotted Perkstar event. Perkstar sends the event as it happens; Zapier does not poll the customer or transaction lists to discover changes. The official app is [available in public Beta](https://zapier.com/apps/perkstar/integrations). Let it create and manage these subscriptions. Do not also paste a **Webhooks by Zapier — Catch Hook** URL into Perkstar for the same event unless you intentionally want two independent deliveries. ## Subscription lifecycle Zapier first creates a paused Perkstar webhook for the selected trigger and retains its signing secret. It then explicitly activates the subscription with the unique, unguessable Zapier HTTPS target URL, event, card, and live/test filters. If activation fails, Zapier asks Perkstar to delete the unused endpoint instead of delivering to a Zap whose setup did not finish. The target URL is not exposed as a Zap field. Perkstar durably creates the delivery before scheduling the outbound POST. Events that do not match that named trigger, selected card, or live/test mode are rejected before a delivery row or outbound request is created. Any `2xx` response is success. Zapier then deduplicates and starts the Zap run using the event fields. When Zapier unsubscribes the trigger, it deletes the app-managed Perkstar endpoint by the ID returned during subscription. Re-enabling the trigger creates a fresh endpoint and signing secret. Historical Zapier tasks remain under Zapier's retention settings. One Zapier OAuth connection can own up to 200 Perkstar webhook subscriptions, including a paused row left by an interrupted cleanup or revoked connection. Each enabled instant trigger normally uses one, and a successful Zapier unsubscribe deletes it and releases capacity. If the connection reaches the limit, turn off or remove unused instant triggers and confirm their unsubscribe completed before enabling another one; Perkstar returns `409 webhook_subscription_limit_reached` instead of silently replacing an existing subscription. Perkstar derives Zapier's subscription identity from the connected business and named trigger plus the Zap ID when the runtime supplies it. Zapier marks that field deprecated and optional, so the official integration falls back to the documented REST Hook target URL instead of refusing activation. Perkstar binds the resulting key to the live webhook row rather than a 24-hour response cache. A lost create response, access-token rotation, delayed retry, failed unsubscribe, or reconnect with the same identity can recover the row and secret. When the Zap ID is available, a changed callback URL recovers it too. The activation PATCH applies the current URL, card, and live/test filters. Deleting the row removes the binding immediately, so an off/on cycle cannot be given a deleted subscription ID or a stale cached capacity error. The first **Customer Lifecycle Group Changed** or Google **Wallet Pass Installed** trigger for a business needs one completed warm-up sweep. Perkstar records existing state without replaying the customer base, then tracks changes after that baseline. If the first workflow must catch every new Google install, enable and test the Zap before promoting its install link. Apple installation remains callback-driven. ## Event identity Perkstar sends the official app this common envelope: ```json theme={null} { "id": "whd_01JEXAMPLE", "type": "transaction.created", "created": 1785312000, "orgId": "org_123", "data": { "enrollmentId": "enr_123", "type": "STAMP", "delta": 1, "occurredAt": "2026-08-02T10:00:00.000Z" } } ``` `id` and `X-Perkstar-Delivery-Id` identify one logical delivery and remain stable across its **automatic retries**. `created` is the source event's `data.occurredAt` time expressed as Unix seconds, so it also remains stable. The `X-Perkstar-Timestamp` signing time and signature are regenerated for each attempt. Zapier uses the stable ID to avoid starting the same logical task twice. The app exposes `id`, `event_type`, `event_created_at`, and `organization_id` to later Zap steps. It flattens the event-specific `data` fields onto the same record. `event_created_at` is the raw `created` value rendered as ISO 8601; it is not the signing-attempt time. Custom webhook endpoints support manual resend in Perkstar. Zapier-owned subscriptions are app-managed and intentionally hidden from those edit, rotate, delete, test, and resend controls. ## Delivery policy | Attempt | Timing | | - | - | | 1 | Immediately | | 2 | 1 minute after the first failure | | 3 | 5 minutes after the second failure | | 4 | 30 minutes after the third failure | * Any HTTP `2xx` response succeeds. * A non-`2xx`, network failure, or response taking longer than ten seconds schedules the next attempt. * An HTTP `410 Gone` response is treated as a permanently removed callback: Perkstar exhausts that delivery immediately and pauses the subscription. * After four failed attempts, the delivery is exhausted and retained for support diagnostics. * Delivery is at least once. A receiver and every downstream write must tolerate duplicates. * Different events can arrive out of order. Use `data.occurredAt` or its equivalent outer `created` value for business ordering, not the signing timestamp. ## Signature handling Perkstar signs the exact raw body with HMAC-SHA256 and sends `X-Perkstar-Signature: t=,v1=`. Zapier's REST Hooks runtime stores Perkstar's one-time subscription secret and makes it available to the live hook handler. Perkstar returns it only on creation or an authenticated idempotent replay of that same app-owned subscription; normal reads never expose it. The official app verifies the signature over the exact raw bytes with a constant-time comparison and rejects timestamps more than five minutes from receipt. Zapier also gives every active Zap a unique HTTPS target URL; do not disclose or reuse it. Developers building a separate receiver should follow [Receive webhooks](/guides/webhooks) and apply the same raw-body verification before parsing JSON. Zapier does not support a separate subscription identity-confirmation handshake; callback HMAC verification is performed inside the official app instead. ## Testing an instant trigger 1. Select the named trigger and the intended Perkstar connected account. 2. If the trigger offers a card filter, choose the explicit active card. 3. Ask Zapier to test or listen for the trigger. 4. Perform the corresponding low-risk event in the connected Perkstar business. 5. Confirm `event_type`, `organization_id`, `event_created_at`, the flattened event-specific fields, and the stable `id` before mapping later steps. The test picker requests up to 20 of the most recent matching records from Perkstar's 90-day recent-event feed. The feed defaults to live events. **New Loyalty Transaction** and **Reward Redeemed** also offer **Include Test Events**; when enabled, both live and test records may be returned. A Card filter, when offered, applies to both recent samples and live delivery. Perkstar applies these filters before sending to Zapier; the app checks them again before starting a Zap run. The diagnostic `webhook.test` event is for Perkstar's generic webhook tools and is not exposed as a named Zapier trigger. If no recent match exists, perform the corresponding low-risk event and test again. A sample is not evidence that every optional field will be non-null on a later live event. ## Timing and scope of observed triggers Some triggers are emitted when Perkstar observes a provider or calculated state, rather than directly from a merchant API request: * **Wallet Pass Installed** fires once when Perkstar first obtains installation evidence for that pass. Apple supplies a device-registration callback. Recently issued Google passes are eligible on the 15-minute projector; older unseen objects use a lower check cadence, and provider responses or projector backlog can extend observation time. Issuing a pass or opening its save link does not fire the trigger. * **Card Scanned** fires only after a successful online lookup in the Perkstar Scanner. An offline cache-only lookup, dashboard search, or POS customer lookup is outside this trigger's contract. * **Customer Card Expired** represents one enrolment reaching one effective expiry instant. If that enrolment is extended and later reaches a different effective expiry, another event can fire. `event_created_at` reflects the expiry instant, even if projection occurs shortly afterwards. * **Customer Lifecycle Group Changed** represents movement among Perkstar's six exclusive lifecycle groups. It does not track saved-segment membership, and an existing customer's initial baseline classification is intentionally suppressed. * **New Customer Referral** is created when one loyalty customer refers another customer. It does not report Perkstar merchant, agency, or partner referrals. Some trigger bodies contain customer or purchaser data. Zap history and every downstream step can retain mapped values. Use only the fields the workflow needs and follow [Data and security](/integrations/zapier/data-security). # Your first safe POS test Source: https://developers.perkstar.co.uk/quickstart Record one test stamp, prove retries do not duplicate it, and check a signed webhook receipt. Use this small workflow when connecting a till: **one completed sale earns one stamp on an existing stamp-card enrolment**. The downloadable example uses the real API and is checked against isolated database fixtures in our release tests. It refuses live keys. It does not create customers or send wallet notifications. A test key can still read the business's real records. Use a dedicated test customer/enrolment agreed with the business, not a customer chosen at random. Test transactions can also trigger webhooks: use a test receiver, and make sure any endpoint set to receive both live and test traffic handles `data.testMode` correctly. The example does not create or alter webhooks. ## 1. Agree the business, owner and minimum access The business needs API access through its POS Connect entitlement (Scale, Enterprise or Franchise, including an eligible active trial). If key creation is unavailable, ask the owner to check the plan and your permissions; do not borrow another business's key. The business owner creates the key in **Settings → API keys → Create API key**. Select **Test** and only **Enrolments: read** (`ENROLLMENTS_READ`) and **Transactions: write** (`TRANSACTIONS_WRITE`). No customer-write, enrolment-write, webhook-write or broad read-only preset is needed. Name it for the system and responsible maintainer, such as `Till setup — Alex`. Set an expiry covering the agreed test period; revoke it when testing ends. The business owns the key and can revoke it. The developer owns its secure storage and the receiving server. Perkstar cannot show the full key again. Keep the secret in a private file named `.perkstar-test.env`, excluded from source control. Set restrictive file permissions (for example `chmod 600 .perkstar-test.env` on macOS/Linux). Do not put it in browser code, screenshots, support messages or a shell command that will remain in history. ```dotenv theme={null} PERKSTAR_API_KEY=pk_test_replace_me PERKSTAR_API_URL=https://dashboard.perkstar.co.uk/api/v1 PERKSTAR_ORG_ID=replace_with_business_id PERKSTAR_CARD_ID=replace_with_active_stamp_card_id PERKSTAR_ENROLLMENT_ID=replace_with_existing_test_enrollment_id PERKSTAR_RECEIPT_ID=test:my-till:store-1:receipt-0001 ``` The business ID here is the API's `organization.id`, not the six-digit account number in the dashboard URL. Read `GET /marketplace/ping` with the test key to check the business and its active cards. Read `GET /enrollments?cardId=` to find the agreed enrolment; follow `next_cursor` if necessary. Inspect these responses privately. Never select the first business or enrolment automatically. The script verifies the business, test mode, scopes, active stamp card and matching active enrolment **before writing**. ## 2. Download, inspect and run the example Use **Node.js 24 or later**. There are no packages to install. [Download pos-test-quickstart.mjs](https://dashboard.perkstar.co.uk/developer-downloads/pos-test-quickstart.mjs) Save the file, inspect it, then run: ```bash theme={null} node --env-file=.perkstar-test.env pos-test-quickstart.mjs ``` The one-stamp request is: ```json theme={null} { "enrollment_id": "your_existing_test_enrollment_id", "type": "STAMP", "delta": 1, "external_transaction_id": "test:my-till:store-1:receipt-0001" } ``` It uses `POST /transactions` and the receipt ID as `Idempotency-Key`. This example is for a completed sale earning **one stamp**, not a spend-to-stamp or points calculation. Use the [POS guide](/guides/pos) for those workflows. Amounts named `amount_pence` use the business currency's minor units; never assume every currency uses two decimal places. ## 3. Check the result, repeat and exercise an error | Check | Expected result | | - | - | | First request | `201` for a new row; `test_mode: true` and a transaction ID | | Repeat identical request and key | Same transaction ID and original status, including `201`; `Idempotent-Replayed: true` | | Same receipt with a different request-cache key | `200` and the same transaction ID: permanent receipt deduplication | | `ADJUST` without a `delta` | `400`, `error.code: missing_field`, `error.param: delta`; no transaction | | Read enrolment again | Balance, redemptions, spend and bonus balance unchanged | The script runs all five checks and prints a compact `PASS` summary without customer records or secrets. Run it again with the **same receipt ID**: it should identify the same transaction. Each genuinely new sale needs its own namespaced permanent reference. Do not generate a new reference on every retry. A real customer being served during the check may change their balance through another channel. That is why an isolated test enrolment is useful. A successful script proves this small API workflow, not every card type or POS feature. ## 4. Receive a signed test event [Download test-webhook-receiver.mjs](https://dashboard.perkstar.co.uk/developer-downloads/test-webhook-receiver.mjs) The receiver accepts `transaction.created` only when `data.testMode` is `true`, plus the dashboard's synthetic `webhook.test`. It validates the signature, five-minute signing timestamp and business ID, then commits a minimal receipt to a local SQLite file before returning `200`. It stores the delivery ID, event type, transaction ID, time and a content hash; it does not store the full customer payload, award another stamp or claim to fulfil an order. Add the separate webhook signing secret to the private environment file: ```dotenv theme={null} PERKSTAR_WEBHOOK_SECRET=replace_with_endpoint_signing_secret PERKSTAR_RECEIPTS_DB=perkstar-test-receipts.sqlite ``` ```bash theme={null} node --env-file=.perkstar-test.env test-webhook-receiver.mjs ``` It listens on `127.0.0.1:8787/webhooks/perkstar`. Perkstar cannot deliver to your localhost. Expose that exact path through an HTTPS ingress you control, then ask the business owner to create a **separate test endpoint** in **Settings → Webhooks**, subscribed to `transaction.created`, filtered to the selected card and **Test** mode. The API test key cannot change webhook configuration. Keep the existing production endpoints intact. Store the one-time signing secret in the receiver's private configuration before testing delivery. Use **Send test** to check connectivity. Then run the POS script with a new test receipt to check a real test-transaction event. Check the endpoint's delivery history and your receiver's receipt; webhook dispatch is asynchronous. | Receiver check | Expected result | | - | - | | Valid signed test transaction | `200` and `receipt: stored` | | Retry/manual resend after restarting the receiver | `200` and `receipt: duplicate`; one saved receipt | | Missing, altered, old or future-dated signature | `400`; nothing saved | | Different business | `403`; nothing saved | | Live transaction | `422 live_event_refused`; nothing saved | | Storage failure | `503`; no success acknowledgement, so Perkstar can retry | The database file must survive restarts. Do not deploy this teaching receiver on an ephemeral filesystem. Before production, use a durable inbox/queue shared by all instances, process real business work asynchronously and make downstream operations idempotent too. Do not simply remove the live-event rejection. Node's built-in SQLite module may show an experimental warning on earlier Node 24 releases; see the [Node SQLite documentation](https://nodejs.org/download/release/latest-v24.x/docs/api/sqlite.html). ## If a check fails * **401:** the key may be wrong or expired. Ask its owner to replace it; do not print the secret while diagnosing it. * **410:** the key has been revoked. Stop using it and ask its owner for a replacement. * **403:** check the selected scopes and business access. Add only the missing permission needed for the intended operation. * **404:** verify the enrolment belongs to the chosen business/card. * **409:** check reused request keys and receipt references. Changing a payload is not a retry of the original operation. * **429:** wait for `Retry-After` before rerunning with the same receipt ID. * **Timeout/5xx:** the write may have succeeded. Keep the receipt ID unchanged, inspect the outcome and use a bounded retry policy; never loop indefinitely. * **Webhook 307/308:** enter the final HTTPS destination directly. Perkstar does not follow redirects; confirm the exact route accepts POST. * **Webhook timeout/5xx:** fix storage/availability and acknowledge promptly after persistence. Resend an exhausted delivery only after correcting the receiver. See [webhook recovery](/guides/webhooks) and [idempotency](/fundamentals/idempotency). ## Finish testing and move deliberately to production Record the expected business, card, connection owner, expiry and successful transaction/delivery IDs. Revoke temporary test keys and disable temporary test endpoints. Keep or remove the local receipt database according to your test-data retention policy. Do not run the all-test-transactions cleanup endpoint on a shared business without agreement: it removes other developers' test rows too. The owner then creates a **separate**, narrowly scoped live key for the finished integration. Store it server-side, use distinct live receipt references, verify one agreed real transaction, and monitor failures. This downloadable script continues to refuse live keys. For future rotation, create a replacement with the required overlap, check last-use evidence and revoke the old key when the consumer has switched; an already expired key is not revived by rotation. # Webhook event catalogue Source: https://developers.perkstar.co.uk/reference/webhook-events Every Perkstar outbound webhook event, with exact data fields and representative payloads. This is the complete public outbound-event catalogue: 29 business events plus the targeted `webhook.test` diagnostic. Event names are stable, dotted, lowercase strings. New optional fields may be added without a version change; existing fields are not repurposed. Every example below shows the event-specific `data` object. Perkstar wraps it in the common envelope documented in [Receive webhooks](/guides/webhooks). ## Field conventions * IDs are opaque strings. Store and compare them exactly. * `occurredAt`, `installedAt`, `expiresAt`, `creditedAt`, `scheduledStart`, `scheduledEnd`, `attendedAt`, and `resolvedAt` are ISO 8601 UTC timestamps. * `created` in the outer envelope is Unix seconds. * Money fields ending in `Pence` are integer minor units. * Nullable fields are sent as JSON `null`; optional fields may be absent. * `testMode: true` identifies a transaction generated with test credentials. ## Customer lifecycle | Event | Sent when | Required `data` fields | Optional `data` fields | | - | - | - | - | | `customer.enrolled` | A customer first joins a card | `enrollmentId`, `cardId`, `source`, `occurredAt` | `customerId` | | `customer.unenrolled` | Access to a card ends | `enrollmentId`, `reason`, `occurredAt` | `cardId`, `customerId` | | `customer.anonymized` | Personal data is anonymised | `customerId`, `customerNumber`, `occurredAt` | `source` | | `customer.group_changed` | A customer moves between lifecycle groups | `customerId`, `previousGroup`, `currentGroup`, `occurredAt` | None | ```json theme={null} { "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "source": "marketplace", "occurredAt": "2026-07-30T10:00:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "reason": "membership_cancelled", "occurredAt": "2026-07-30T10:10:00.000Z" } ``` ```json theme={null} { "customerId": "cus_123", "customerNumber": 1042, "source": "api", "occurredAt": "2026-07-30T10:15:00.000Z" } ``` ```json theme={null} { "customerId": "cus_123", "previousGroup": "new", "currentGroup": "regulars", "occurredAt": "2026-07-30T10:20:00.000Z" } ``` `previousGroup` and `currentGroup` use one of `vips`, `regulars`, `new`, `slipping`, `atRisk`, or `lost`; `currentGroup` can be `null` if a customer no longer classifies into a group. These are Perkstar's six exclusive lifecycle groups, not operator-created saved segments. The first classification is stored as a baseline without emitting `customer.group_changed`, so connecting a new endpoint does not replay every existing customer. For a business's first interested endpoint, that baseline is established on the next completed projection. Tracking begins after the warm-up sweep, so a transition inside that initial window becomes baseline state rather than an event. ## Wallet, scanner, expiry, and referrals | Event | Sent when | Required `data` fields | Nullable `data` fields | | - | - | - | - | | `wallet.installed` | Perkstar first observes a pass installed in Apple or Google Wallet | `walletPassId`, `enrollmentId`, `customerId`, `cardId`, `platform`, `detectionSource`, `installedAt`, `occurredAt` | None | | `card.scanned` | An online Perkstar Scanner lookup successfully resolves a customer card | `scanId`, `enrollmentId`, `customerId`, `cardId`, `credentialType`, `walletPassId`, `platform`, `locationId`, `occurredAt` | `walletPassId`, `platform`, `locationId` | | `card.expired` | One customer enrolment reaches its effective card expiry | `enrollmentId`, `customerId`, `cardId`, `cardType`, `expiresAt`, `expirySource`, `occurredAt` | None | | `referral.created` | One customer refers another customer to the same loyalty-card programme | `referralId`, `cardId`, `referrerEnrollmentId`, `referrerCustomerId`, `referredEnrollmentId`, `referredCustomerId`, `status`, `bonusTiming`, `creditedAt`, `occurredAt` | `creditedAt` | ```json theme={null} { "walletPassId": "pass_apple_123", "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "platform": "apple", "detectionSource": "apple_device_registration", "installedAt": "2026-07-30T10:25:00.000Z", "occurredAt": "2026-07-30T10:25:00.000Z" } ``` ```json theme={null} { "scanId": "550e8400-e29b-41d4-a716-446655440000", "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "credentialType": "wallet_pass_serial", "walletPassId": "pass_apple_123", "platform": "apple", "locationId": "loc_high_street", "occurredAt": "2026-07-30T10:30:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "cardType": "POINTS", "expiresAt": "2026-07-30T10:35:00.000Z", "expirySource": "fixed_term", "occurredAt": "2026-07-30T10:35:00.000Z" } ``` ```json theme={null} { "referralId": "referral_123", "cardId": "card_123", "referrerEnrollmentId": "enr_referrer_123", "referrerCustomerId": "cus_referrer_123", "referredEnrollmentId": "enr_referred_123", "referredCustomerId": "cus_referred_123", "status": "credited", "bonusTiming": "on_signup", "creditedAt": "2026-07-30T10:40:00.000Z", "occurredAt": "2026-07-30T10:40:00.000Z" } ``` ### Observation boundaries * `wallet.installed` is the first provider-owned installation observation per pass and platform. Creating a pass or opening a save link is not an install. Apple reports a device registration directly. Recently issued Google passes are eligible on the 15-minute projector; older unseen objects back off to a lower check cadence, and provider responses or projector backlog can extend observation time. Do not treat 15 minutes as a delivery SLA. `platform` is `apple` or `google`, and `detectionSource` is `apple_device_registration` or `google_has_users`. When a business enables its first interested endpoint, the next completed Google check stores existing state as a no-event baseline; Google-install tracking begins after that warm-up sweep. * `card.scanned` covers a successful **online** lookup in the Perkstar Scanner. It does not fire for an offline IndexedDB cache lookup, a dashboard customer search, or a POS integration lookup. `credentialType` is `wallet_pass_serial`, `enrollment_barcode`, or `physical_keyring`. `walletPassId` and `platform` are non-null only for a direct wallet-pass serial; shared enrolment barcodes and physical keyrings are platform-neutral. * `card.expired` is per enrolment and effective expiry instant, not one event for the card template. `expirySource` is `enrollment_override`, `fixed_date`, or `fixed_term`. Extending or reissuing the enrolment can produce another event when the later effective expiry is reached. * `referral.created` is a customer-to-customer loyalty referral. It is not a merchant, agency, or partner-referral invitation. `status` is `pending` or `credited`; `bonusTiming` is `on_signup` or `on_first_purchase`, and `creditedAt` is `null` while a first-purchase referral remains pending. ## Loyalty activity | Event | Sent when | Required `data` fields | Optional `data` fields | | - | - | - | - | | `transaction.created` | A loyalty-ledger row is committed | `enrollmentId`, `type`, `delta`, `occurredAt` | `transactionId`, `cardId`, `customerId`, `amountPence`, `balanceAfter`, `reversesTransactionId`, `reason`, `source`, `testMode`, `externalTransactionId`, `promotionId`, `promotionUseId`, `promotionUseVoided` | | `coupon.redeemed` | A coupon card is redeemed | `enrollmentId`, `cardId`, `customerId`, `occurredAt` | None | | `reward.redeemed` | A reward, offer, voucher, or milestone is redeemed | `enrollmentId`, `cardId`, `cost`, `occurredAt` | `transactionId`, `milestoneId`, `stampRewardId`, `rewardTierId`, `offerId`, `offerTitle`, `discountAmountPence`, `discountKind`, `basketAmountPence`, `source`, `testMode`, `promotionId`, `promotionName`, `promotionRewardKind`, `promotionRewardMultiplier`, `promotionRewardPercent`, `promotionRewardAmountPence`, `promotionRewardText`, `promotionCurrency`, `promotionTerms` | | `tier.changed` | A status, cashback, or discount tier changes | `enrollmentId`, `cardId`, `newTierName`, `kind`, `occurredAt` | `source` | `transaction.created.type` is normally `STAMP`, `REDEEM`, or `ADJUST`. `tier.changed.kind` is `status`, `cashback`, or `discount`. ```json theme={null} { "transactionId": "txn_123", "enrollmentId": "enr_123", "customerId": "cus_123", "cardId": "card_123", "type": "STAMP", "delta": 1, "amountPence": 1250, "balanceAfter": 6, "externalTransactionId": "odoo:order:94721", "promotionId": null, "promotionUseId": null, "promotionUseVoided": null, "source": "api", "testMode": false, "occurredAt": "2026-07-30T11:00:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_123", "cardId": "card_coupon_123", "customerId": "cus_123", "occurredAt": "2026-07-30T11:05:00.000Z" } ``` ```json theme={null} { "transactionId": "txn_124", "enrollmentId": "enr_123", "cardId": "card_123", "cost": 10, "rewardTierId": "tier_123", "promotionId": "promo_123", "promotionName": "Double points weekend", "promotionRewardKind": "MULTIPLIER", "promotionRewardMultiplier": 2, "promotionRewardPercent": null, "promotionRewardAmountPence": null, "promotionRewardText": "Double points", "promotionCurrency": "GBP", "promotionTerms": "Valid once per customer.", "discountAmountPence": 500, "discountKind": "FIXED", "basketAmountPence": 2500, "source": "api", "testMode": false, "occurredAt": "2026-07-30T11:10:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_123", "cardId": "card_123", "newTierName": "Gold", "kind": "cashback", "source": "api", "occurredAt": "2026-07-30T11:15:00.000Z" } ``` ## Tickets, gifts, and multipasses | Event | Sent when | Required `data` fields | Optional `data` fields | | - | - | - | - | | `ticket.purchased` | A paid ticket fulfilment completes | `enrollmentId`, `cardId`, `pricePence`, `sessionId`, `firingId`, `occurredAt` | None | | `ticket.cancelled` | A ticket event is cancelled | `cardId`, `cardName`, `cancellationId`, `attendeeCount`, `reason`, `willRefund`, `occurredAt` | None | | `ticket.refunded` | A ticket payment is refunded or lost to chargeback | `enrollmentId`, `cardId`, `paymentIntentId`, `occurredAt` | `refundAmountPence`, `reason` | | `gift.purchased` | A paid gift fulfilment completes | `giftPurchaseId`, `enrollmentId`, `cardId`, `amountPence`, `purchaserEmail`, `recipientEmail`, `occurredAt` | None | | `gift.redeemed` | Value is spent from a gift card | `enrollmentId`, `customerId`, `cardId`, `amountPence`, `remainingPence`, `occurredAt` | None | | `multipass.purchased` | A multipass is purchased or topped up | `enrollmentId`, `cardId`, `customerId`, `visitCount`, `bundleName`, `topUp`, `sessionId`, `firingId`, `occurredAt` | None | ```json theme={null} { "enrollmentId": "enr_ticket_123", "cardId": "card_ticket_123", "pricePence": 2500, "sessionId": "checkout_session_123", "firingId": "fulfilment_123", "occurredAt": "2026-07-30T12:00:00.000Z" } ``` ```json theme={null} { "cardId": "card_ticket_123", "cardName": "Summer tasting", "cancellationId": "cancel_123", "attendeeCount": 18, "reason": "Venue unavailable", "willRefund": true, "occurredAt": "2026-07-30T12:05:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_ticket_123", "cardId": "card_ticket_123", "refundAmountPence": 2500, "paymentIntentId": "payment_123", "occurredAt": "2026-07-30T12:10:00.000Z" } ``` ```json theme={null} { "giftPurchaseId": "gift_123", "enrollmentId": "enr_gift_123", "cardId": "card_gift_123", "amountPence": 5000, "purchaserEmail": "buyer@example.com", "recipientEmail": "recipient@example.com", "occurredAt": "2026-07-30T12:15:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_gift_123", "customerId": "cus_123", "cardId": "card_gift_123", "amountPence": 1250, "remainingPence": 3750, "occurredAt": "2026-07-30T12:20:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_multi_123", "cardId": "card_multi_123", "customerId": "cus_123", "visitCount": 10, "bundleName": "Ten visits", "topUp": false, "sessionId": "checkout_session_456", "firingId": "fulfilment_456", "occurredAt": "2026-07-30T12:25:00.000Z" } ``` ## Memberships | Event | Sent when | Required `data` fields | Conditional fields | | - | - | - | - | | `membership.purchased` | A recurring or one-off membership first activates | `enrollmentId`, `cardId`, `tierId`, `occurredAt` | Recurring purchases include `subscriptionId`; one-off purchases include `billingInterval` | | `membership.renewed` | A recurring membership advances to a new billing period | `enrollmentId`, `cardId`, `tierId`, `subscriptionId`, `occurredAt` | None | | `membership.cancelled` | A recurring membership becomes cancelled or incomplete-expired | `enrollmentId`, `cardId`, `subscriptionId`, `occurredAt` | None | ```json theme={null} { "enrollmentId": "enr_member_123", "cardId": "card_member_123", "tierId": "tier_123", "subscriptionId": "subscription_123", "occurredAt": "2026-07-30T13:00:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_member_123", "cardId": "card_member_123", "tierId": "tier_123", "subscriptionId": "subscription_123", "occurredAt": "2026-08-30T13:00:00.000Z" } ``` ```json theme={null} { "enrollmentId": "enr_member_123", "cardId": "card_member_123", "subscriptionId": "subscription_123", "occurredAt": "2026-09-12T13:00:00.000Z" } ``` ## Engagement | Event | Sent when | Required `data` fields | Optional `data` fields | | - | - | - | - | | `feedback.submitted` | A customer submits card feedback | `enrollmentId`, `cardId`, `rating`, `hasComment`, `occurredAt` | None | | `automation.fired` | An automated-message firing is recorded | `automationId`, `customerId`, `occurredAt` | None | | `broadcast.sent` | A wallet broadcast reaches terminal delivery processing | `broadcastId`, `cardId`, `targetCount`, `failureCount`, `occurredAt` | None | ```json theme={null} { "enrollmentId": "enr_123", "cardId": "card_123", "rating": 5, "hasComment": true, "occurredAt": "2026-07-30T14:00:00.000Z" } ``` ```json theme={null} { "automationId": "automation_123", "customerId": "cus_123", "occurredAt": "2026-07-30T14:05:00.000Z" } ``` ```json theme={null} { "broadcastId": "broadcast_123", "cardId": "card_123", "targetCount": 250, "failureCount": 3, "occurredAt": "2026-07-30T14:10:00.000Z" } ``` ## Bookings All booking events use the same schema. Only the event name and resulting `status` differ. | Event | Resulting `status` | | - | - | | `booking.created` | `PENDING` | | `booking.confirmed` | `CONFIRMED` | | `booking.attended` | `ATTENDED` | | `booking.no_show` | `NO_SHOW` | | `booking.cancelled` | `CANCELLED` | Required fields are `id`, `provider`, `providerBookingId`, `status`, `scheduledStart`, `loyaltyCredited`, `source`, and `occurredAt`. The fields `customerId`, `cardId`, `scheduledEnd`, `attendedAt`, and `resolvedAt` are nullable. `serviceLabel` and `staffLabel` contain the provider labels saved on the booking. Provider lifecycles can skip states. Acuity appointments enter Perkstar as `CONFIRMED`, normally have no `customerId` until attendance matching runs, and are auto-attended by the Perkstar scheduler after their end time plus 15 minutes. Acuity does not emit a `PENDING` booking. ```json theme={null} { "id": "booking_123", "provider": "GENERIC_WEBHOOK", "providerBookingId": "external-booking-123", "status": "PENDING", "customerId": null, "cardId": "card_123", "serviceLabel": "Consultation", "staffLabel": "Alex", "scheduledStart": "2026-08-02T09:00:00.000Z", "scheduledEnd": "2026-08-02T09:30:00.000Z", "attendedAt": null, "resolvedAt": null, "loyaltyCredited": false, "source": "adapter", "occurredAt": "2026-07-30T15:00:00.000Z" } ``` ```json theme={null} { "id": "booking_123", "provider": "ACUITY", "providerBookingId": "987654", "status": "CONFIRMED", "customerId": null, "cardId": "card_123", "serviceLabel": "Consultation", "staffLabel": "Alex", "scheduledStart": "2026-08-02T09:00:00.000Z", "scheduledEnd": "2026-08-02T09:30:00.000Z", "attendedAt": null, "resolvedAt": null, "loyaltyCredited": false, "source": "adapter", "occurredAt": "2026-07-30T15:05:00.000Z" } ``` ```json theme={null} { "id": "booking_123", "provider": "ACUITY", "providerBookingId": "987654", "status": "ATTENDED", "customerId": "cus_123", "cardId": "card_123", "serviceLabel": "Consultation", "staffLabel": "Alex", "scheduledStart": "2026-08-02T09:00:00.000Z", "scheduledEnd": "2026-08-02T09:30:00.000Z", "attendedAt": "2026-08-02T09:45:00.000Z", "resolvedAt": null, "loyaltyCredited": true, "source": "cron", "occurredAt": "2026-08-02T09:45:00.000Z" } ``` ```json theme={null} { "id": "booking_123", "provider": "ACUITY", "providerBookingId": "987654", "status": "NO_SHOW", "customerId": "cus_123", "cardId": "card_123", "serviceLabel": "Consultation", "staffLabel": "Alex", "scheduledStart": "2026-08-02T09:00:00.000Z", "scheduledEnd": "2026-08-02T09:30:00.000Z", "attendedAt": "2026-08-02T09:45:00.000Z", "resolvedAt": "2026-08-02T10:00:00.000Z", "loyaltyCredited": false, "source": "adapter", "occurredAt": "2026-08-02T10:00:00.000Z" } ``` ```json theme={null} { "id": "booking_123", "provider": "ACUITY", "providerBookingId": "987654", "status": "CANCELLED", "customerId": "cus_123", "cardId": "card_123", "serviceLabel": "Consultation", "staffLabel": "Alex", "scheduledStart": "2026-08-02T09:00:00.000Z", "scheduledEnd": "2026-08-02T09:30:00.000Z", "attendedAt": null, "resolvedAt": "2026-07-31T17:00:00.000Z", "loyaltyCredited": false, "source": "adapter", "occurredAt": "2026-07-31T17:00:00.000Z" } ``` ## Diagnostics | Event | Sent when | Required `data` fields | | - | - | - | | `webhook.test` | An operator sends a test from one webhook's settings | `message`, `webhookId`, `triggeredAt` | The targeted test ignores the endpoint's subscription filter, but the webhook must be active. ```json theme={null} { "message": "This is a test event from Perkstar.", "webhookId": "webhook_123", "triggeredAt": "2026-07-30T16:00:00.000Z" } ``` # Python SDK Source: https://developers.perkstar.co.uk/sdks/python Use the official Perkstar Python client with retries, cursor pagination, typed errors, and webhook verification. The official synchronous SDK supports Python 3.9 and newer. It covers every operation in the public v1 API and is suited to Odoo modules, POS middleware, scheduled syncs, and backend services. ## Install Install the verified release from PyPI: ```bash theme={null} python -m pip install "perkstar==0.1.2" ``` The wheel has no compiled extensions, so the same file works on Linux, macOS, and Windows. Releases are built and tested in GitHub Actions, published with PyPI Trusted Publishing, and accompanied by digital attestations. No long-lived PyPI password or upload token is stored in the repository. ## Create a client ```python theme={null} import os from perkstar import Perkstar with Perkstar( api_key=os.environ["PERKSTAR_API_KEY"], user_agent="MyOdooConnector/1.0", ) as perkstar: context = perkstar.marketplace.ping() print(context["data"]["organization"]["name"]) ``` Pass `oauth_access_token=` instead of `api_key=` when your integration uses OAuth. Pass exactly one credential type. ## Post a POS transaction ```python theme={null} result = perkstar.marketplace.accrue( { "identifier": {"external_ref": "odoo:4:partner:981"}, "card_id": "card_123", "transaction": { "type": "STAMP", "delta": 1, "external_transaction_id": "odoo:4:pos_order:94721", }, }, idempotency_key="odoo:4:pos_order:94721:loyalty", ) print(result["enrollment"]["balance"]) ``` The SDK generates an idempotency key for a new POST and preserves it across automatic retries. Supply your own stable key when a durable job may restart in a different process. ## Pagination ```python theme={null} for customer in perkstar.customers.list(limit=100): sync_customer(customer) ``` Requests are lazy and follow `next_cursor` until the API reports no more rows. An empty or repeated cursor stops with an error instead of looping forever. ## Typed errors ```python theme={null} from perkstar import PerkstarError, PerkstarRateLimitError try: post_loyalty() except PerkstarRateLimitError as error: schedule_retry(error.retry_after) except PerkstarError as error: print(error.code, error.request_id) ``` Network failures, `408`, `429`, and retryable `5xx` responses are retried up to three times by default. The client honours `Retry-After` and keeps the API error code, HTTP status, request ID, and API version on the raised exception. ## Verify webhooks ```python theme={null} from perkstar import verify_webhook_signature event = verify_webhook_signature( raw_request_body, request.headers["X-Perkstar-Signature"], webhook_secret, ) ``` Pass the exact raw `str` or `bytes` body. The helper uses constant-time HMAC comparison and rejects timestamps outside a five-minute replay window. ## Verify the hosted fallback Partners operating in locked-down environments can use the matching Perkstar-hosted release and checksum: ```bash theme={null} curl --fail --remote-name \ https://dashboard.perkstar.co.uk/developer-downloads/perkstar-0.1.2-py3-none-any.whl curl --fail --remote-name \ https://dashboard.perkstar.co.uk/developer-downloads/SHA256SUMS sha256sum --check SHA256SUMS --ignore-missing ``` The [source distribution](https://dashboard.perkstar.co.uk/developer-downloads/perkstar-0.1.2.tar.gz) is also available for inspection and local builds. # TypeScript SDK Source: https://developers.perkstar.co.uk/sdks/typescript Use the official typed Perkstar client with automatic retries, pagination, and webhook verification. The official SDK supports Node.js 18+ and ships ESM and CommonJS builds with no runtime dependencies. ```bash theme={null} npm install @perkstar/api-client ``` ## Create a client ```ts theme={null} import { PerkstarClient } from "@perkstar/api-client"; const perkstar = new PerkstarClient({ apiKey: process.env.PERKSTAR_API_KEY!, userAgent: "MyOdooConnector/1.0", }); const context = await perkstar.marketplace.ping(); console.log(context.data.organization.name); ``` You can pass an OAuth access token instead of an API key: ```ts theme={null} const perkstar = new PerkstarClient({ oauthAccessToken: accessToken, }); ``` Pass exactly one credential type. ## Post a POS transaction ```ts theme={null} const result = await perkstar.marketplace.accrue( { identifier: { external_ref: "odoo:4:partner:981" }, card_id: "card_123", transaction: { type: "STAMP", delta: 1, external_transaction_id: "odoo:4:pos_order:94721", }, }, { idempotencyKey: "odoo:4:pos_order:94721:loyalty", }, ); console.log(result.enrollment.balance); ``` The SDK generates an idempotency key for each new POST call and keeps it across its automatic retries. Pass your own stable key when a job may restart in a new process. ## Pagination ```ts theme={null} for await (const customer of perkstar.customers.list({ limit: 100 })) { await syncCustomer(customer); } ``` ## Typed errors ```ts theme={null} import { PerkstarRateLimitError, PerkstarValidationError, } from "@perkstar/api-client"; try { await postLoyalty(); } catch (error) { if (error instanceof PerkstarValidationError) { console.error(error.code, error.requestId); return; } if (error instanceof PerkstarRateLimitError) { throw error; // let the durable job retry later } throw error; } ``` By default the client retries network errors, `429`, and retryable `5xx` responses up to three times, honours `Retry-After`, and times out each request after 30 seconds. ## Verify webhooks ```ts theme={null} import { verifyWebhookSignature } from "@perkstar/api-client/webhooks"; const event = verifyWebhookSignature({ payload: rawBody, signature: signatureHeader, secret: process.env.PERKSTAR_WEBHOOK_SECRET!, }); ``` The helper uses constant-time HMAC comparison and rejects timestamps outside a five-minute tolerance by default. The REST API currently contains a few endpoints that are not yet wrapped by the SDK, including locations and direct wallet pushes. Use the generated API reference for those calls while keeping the same bearer and retry rules. # API availability Source: https://developers.perkstar.co.uk/support/api-availability See which Perkstar resources are stable public contracts and which workflows are not yet partner-ready. This matrix is the honest boundary of the public v1 API. A dashboard feature or internal provider adapter is not automatically a supported public resource. | Capability | Public status | Supported path | | - | - | - | | Customers | Available | List, retrieve, create/upsert, update, and anonymise through `/customers` | | Enrolments | Available | List, retrieve, create, and update status through `/enrollments` | | Transactions | Available | List and post loyalty ledger entries through `/transactions` | | Loyalty cards | Read-only | List and retrieve card configuration through `/cards` | | Locations | Read-only | List mapped business locations through `/locations` | | Wallet pushes | Write-only | Send to an enrolment through `/pushes` | | Outbound webhooks | Available | Configure endpoints through `/webhooks`; receive the [event catalogue](/reference/webhook-events) | | POS/ERP loyalty | Available | Use `/marketplace/ping`, `/marketplace/accrue`, `/marketplace/enroll`, and `/marketplace/reverse` | | Rewards and vouchers | Event/workflow access | Observe earning and redemption through enrolments, transactions, and webhooks; no first-class public CRUD resource yet | | Tiers and benefits | Event/read context | Card and event context is available; tier and benefit management is not a public contract yet | | Orders | Partner-owned | Send stable external transaction IDs and amounts; Perkstar does not expose a generic order resource | | Coupons | Redemption events | `coupon.redeemed` is public; coupon catalogue and redemption APIs are not yet public | ## What partner-ready means Perkstar publishes a resource only after it has: * an organisation and scope boundary; * stable identifiers and idempotency rules; * documented validation, errors, and rate limits; * test-mode behaviour that cannot alter live data; * OpenAPI, TypeScript, Python, and Postman parity; and * webhook or reconciliation behaviour where eventual consistency matters. Until those conditions are met, use the documented public workflow rather than calling dashboard actions or internal routes. Internal endpoints can change without notice and are not covered by the API versioning policy. ## Designing future functionality For reward, voucher, tier, benefit, coupon, or order requirements that the matrix does not cover, contact [support@perkstar.co.uk](mailto:support@perkstar.co.uk) with the provider, merchant journey, required writes, and reconciliation model. This lets Perkstar promote a complete contract instead of exposing a fragile partial endpoint. # Go-live checklist Source: https://developers.perkstar.co.uk/support/go-live-checklist Verify security, correctness, and operational recovery before sending production traffic. Use this checklist for every integration, even when the first test looked simple. Loyalty errors are customer-visible and often occur during a busy sale. ## Credentials * [ ] A new live key exists for this integration only. * [ ] The key has the minimum scopes required. * [ ] The secret is stored server-side and is absent from source control and logs. * [ ] The owner and rotation process are documented. * [ ] The test key is not used in production. ## Customer and card mapping * [ ] Upstream customer references are stable and namespaced. * [ ] Every store or programme maps to an explicit Perkstar `card_id` when several cards exist. * [ ] Perkstar `locationId` mappings have been checked for every venue. * [ ] Current opaque and legacy wallet barcode values are passed through unchanged. * [ ] Consent flags are copied only from an auditable consent source. ## Transactions * [ ] Every POST has a stable `Idempotency-Key`. * [ ] POS awards include a permanent `external_transaction_id`. * [ ] A simulated timeout followed by a retry creates one result. * [ ] A duplicate upstream webhook creates one result. * [ ] Full refunds reverse the original transaction. * [ ] Partial-refund behaviour has been agreed with the business. * [ ] The card type rejects incompatible transaction types cleanly. ## Failure handling * [ ] `429` respects `Retry-After`. * [ ] Network errors and retryable `5xx` responses enter a durable retry queue. * [ ] Non-retryable `4xx` failures are visible to an operator. * [ ] Offline operations retain their original stable IDs. * [ ] Reconciliation can detect an order with no matching Perkstar transaction. * [ ] Logs retain `X-Request-Id` but never API keys or full personal payloads. ## Webhooks * [ ] Signatures are verified against the raw body. * [ ] Event IDs are deduplicated in persistent storage. * [ ] Test events are separated using `testMode`. * [ ] Events can arrive more than once or out of order. * [ ] The receiver acknowledges only after durable storage or processing. ## Launch 1. Process one low-risk live transaction. 2. Confirm the Perkstar ledger and wallet update. 3. Reverse it and confirm both systems. 4. Enable one location or small traffic group. 5. Monitor errors, retries, and reconciliation before widening traffic. # API status Source: https://developers.perkstar.co.uk/support/status Check live Perkstar API, dashboard, scanner, wallet, webhook, billing, and POS service health. Use the [Perkstar status page](https://dashboard.perkstar.co.uk/status) before investigating an integration failure. It combines direct dependency checks with the production synthetic journey that runs across Perkstar services. View current component health, the latest automated check, 24-hour check success, and recent affected components. ## Components | Component | What is checked | | - | - | | Public API | Database readiness, cache access, and API health | | Dashboard | Business sign-in and application availability | | Scanner | Staff sign-in, scanner loading, and version delivery | | Wallet services | Apple Wallet pass delivery boundaries | | Webhooks and billing | Webhook ingestion and Stripe connectivity | | POS integrations | Scheduled POS synchronization smoke mode | The page deliberately does not stay silently green when monitoring is late. If the synthetic run has not completed within its expected window, components show as degraded until a fresh result arrives. ## Machine-readable status ```bash theme={null} curl https://dashboard.perkstar.co.uk/api/status ``` The JSON endpoint allows cross-origin GET requests and returns the overall condition, component conditions, 24-hour success percentages, timestamps, and recent affected component names. It never exposes internal exception messages or tenant data. Include the `X-Request-Id` from a failed API response when contacting support. The status page identifies broad service health; the request ID lets Perkstar trace one integration call. # Versioning and compatibility Source: https://developers.perkstar.co.uk/support/versioning Understand Perkstar API versions, SDK releases, and safe upgrade practices. The REST API is date-versioned. Every response includes `X-API-Version`, and the OpenAPI document identifies the contract it describes. ## Compatibility policy Within a published API version, Perkstar may: * add optional response fields; * add new endpoints or webhook event types; * add optional request fields; and * improve validation and error detail without changing successful behaviour. Integrations should ignore unknown response fields and webhook event types they do not handle. Do not model API objects as closed dictionaries unless your decoder supports forward-compatible fields. A breaking change requires a new version and a migration period. The current OpenAPI description states the active deprecation policy. ## SDK versions `@perkstar/api-client` follows semantic versioning: * patch releases contain compatible fixes; * minor releases add compatible functionality; and * major releases may require code changes or pin a newer API contract. Pin a supported version range, run contract tests in CI, and review the [changelog](/changelog) before upgrading. ## Detecting drift Log `X-API-Version` with request IDs. During deployment, compare the SDK's exported `API_VERSION` with the server header and alert on an unexpected value. # Connect with MCP Source: https://developers.perkstar.co.uk/tools/mcp Give compatible AI clients secure, read-only access to Perkstar business reporting through OAuth. Perkstar exposes a Model Context Protocol server for conversational reporting. The connection is read-only: it can inspect loyalty data and analytics, but it cannot change customers, balances, cards, messages, or account settings. ## Connection details | Setting | Value | | - | - | | Server URL | `https://dashboard.perkstar.co.uk/api/mcp` | | Transport | Stateless Streamable HTTP, JSON response mode | | Authentication | OAuth 2.0 Authorization Code with PKCE | | Required plan | Growth or above; Perkstar staff access is separate | | Mutations | None | Add the server URL to a compatible MCP client. The client discovers Perkstar's authorization, registration, token, and revocation endpoints automatically. The business owner or manager signs in, selects the organisation, and approves the read-only `MCP` scope. A Perkstar API key cannot access MCP. Use the OAuth flow started by the MCP client; do not paste a dashboard API key into an AI application. ## Available business tools Business overview, loyalty-card health, locations, and unusual-activity summaries. Search customers, inspect a customer, view behavioural groups, and rank top customers. Query stamps, points, redemptions, adjustments, and outstanding rewards. Performance, feedback, memberships, bookings, referrals, and broadcast reporting. The server also provides guided prompts for a weekly performance review, win-back candidates, and card health checks. Tools return current Perkstar data; the AI client decides how to explain it. ## Security model 1. OAuth consent pins the token to one Perkstar organisation. 2. The server checks the token scope, expiry, revocation, plan, and consenting user on every request. 3. Tool schemas reject unknown fields and keep result sizes bounded. 4. Requests appear in the organisation's API activity log and follow its seven-day API audit retention. 5. Revoking the connection invalidates the access and refresh token pair. Perkstar staff tools can query across organisations, but they are exposed only when the consenting user independently passes the Perkstar staff check. A normal business connection cannot request or smuggle an organisation override. ## Client compatibility The server supports MCP protocol versions `2025-06-18`, `2025-03-26`, and `2024-11-05`. It implements `initialize`, `ping`, tool listing and calls, and prompt listing and retrieval. It does not expose an SSE stream, resources, sampling, or write tools. For a bespoke application rather than an MCP client, use the [marketplace OAuth guide](/guides/oauth-marketplace) and public REST API. # Run the API in Postman Source: https://developers.perkstar.co.uk/tools/postman Import the official Perkstar collection and environment for repeatable, end-to-end API testing. The official Postman collection is generated from the same OpenAPI contract as this reference. It contains every public v1 operation, example bodies, inherited bearer authentication, request tracing checks, and automatic ID capture for multi-step testing. This collection is a testing tool, not a second source of API truth. Guides explain behaviour and the OpenAPI reference defines the contract; the Postman files make that contract quick to exercise. In Postman choose **Import → Link** and paste this URL. Requests are grouped by customers, enrolments, transactions, cards, webhooks, locations, pushes, and marketplace operations. Production base URL and safe placeholder variables. It contains no live credential. ## Import and connect In Postman, choose **Import → Link** and paste: ```text theme={null} https://dashboard.perkstar.co.uk/developer-downloads/perkstar-public-api.postman_collection.json ``` Import the environment file from the card above, then select **Perkstar Production** in the environment menu. Create a read-only test key in **Dashboard → Settings → API keys**. Replace the `api_key` environment value with that key and mark the value as secret. Open **Marketplace → Auth check + org context** and send the request. A successful response identifies the connected business and available cards. Run the **Cards** folder first. Collection tests verify the API version, request ID, and absence of a server error on every response. ## Write requests POST requests use Postman's `{{$guid}}` dynamic variable for a fresh `Idempotency-Key`. Replace it with a stable business reference when testing a job that may be replayed from another process. For a manual retry, keep the resolved key from the first request instead of generating another one. The collection includes write and delete requests. A read-only key keeps those requests safely blocked. Add only the scopes needed for the operation you are deliberately testing, and use a test key before switching to live. ## Keep it current The collection and environment are regenerated whenever the canonical API contract changes. CI rejects a release if the checked-in files are stale or if their method and path coverage differs from the OpenAPI reference. ## What to run before launch Run **Marketplace → Auth check + org context**. Confirm the response names the intended business, reports the expected key mode, and lists the cards your integration expects. Run the Cards, Locations, Customers, and Enrolments folders with a read-only test key. Collection tests verify request IDs and reject unexpected server errors. Use a test key and an existing enrolment. Send the same write twice with the same resolved `Idempotency-Key`; the second response must replay safely rather than apply loyalty twice. Create a test endpoint, store the signing secret, send `webhook.test`, and verify the raw request body before parsing it. Then compare your handler against the [event catalogue](/reference/webhook-events).