> For the complete documentation index, see [llms.txt](https://help.openloyalty.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.openloyalty.io/implementation-guide/plan-and-foundations/integration-architecture.md).

# Integration Architecture

How Open Loyalty fits between your member channels and your other systems, and what the integration layer in between is responsible for.

Open Loyalty is headless and API-first. Your channels (website, app, e-commerce, stores) send it what members do; it applies the programme's rules, keeps balances and history, and tells other systems what happened.

<figure><img src="https://226878483-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FZ4Fuoa1PTF0DrNTgjzJu%2Fuploads%2Fgit-blob-53738b40a84c77b79f46e975f37f2cd856e91ff1%2Fig-integration-architecture.png?alt=media" alt="Member channels call an integration layer, which calls the Open Loyalty REST API. Open Loyalty sends webhooks to the integration layer and to CRM or marketing automation, and data exports to a data warehouse." width="364"><figcaption><p>Reference architecture</p></figcaption></figure>

## The integration layer

Most programmes put a small service — the **integration layer** — between their channels and Open Loyalty, rather than calling the API from each channel. It can be a dedicated middleware, an iPaaS flow or part of an existing backend (e.g. an e-commerce platform's server-side extensions).

It is responsible for:

| Responsibility              | Why                                                                                                                                                                                                                                   |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Holding the API key**     | An API key acts with the permissions of the admin it belongs to and doesn't expire unless you set an expiry. It must never reach a browser or an app.                                                                                 |
| **Mapping identifiers**     | Channels know a member by their own ID (customer number, email). The integration layer turns that into the identifier Open Loyalty matches on — see [Member identity](/implementation-guide/plan-and-foundations/member-identity.md). |
| **Transforming data**       | Orders, receipts and app events become Open Loyalty transactions and custom events.                                                                                                                                                   |
| **Retries and idempotency** | Transient failures (`429`, `5xx`, timeouts) are retried with backoff; every event carries a stable ID so a retry can't be counted twice.                                                                                              |
| **Logging**                 | Every failed request is logged with its payload, so it can be replayed or investigated.                                                                                                                                               |

Member-facing channels — including those that only display data, such as balance, rewards and history — call the integration layer, which authenticates the member in your own system and reads from Open Loyalty on their behalf. Don't call Open Loyalty directly from a browser or app.

## Synchronous and asynchronous flows

| Direction                    | Mechanism                                                                               | Typical use                                                                                                          |
| ---------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Channels → Open Loyalty      | REST API, synchronous                                                                   | Register and update members, send transactions and custom events, read balances, list and redeem rewards             |
| Open Loyalty → your systems  | [Webhooks](https://help.openloyalty.io/technical-guide/webhooks/overview), asynchronous | Balance changes, tier changes, rewards bought, campaign effects — to update CRM, trigger messages or refresh a cache |
| Open Loyalty → data platform | Data exports                                                                            | Reporting and reconciliation in a data warehouse                                                                     |

Design every webhook consumer for at-least-once delivery: the same event can arrive more than once, and events can arrive out of order. See the [webhook best practices](https://help.openloyalty.io/technical-guide/webhooks/best-practices).

## Where the business logic lives

Keep programme rules in Open Loyalty, not in the integration layer:

* **Earning** — how many points a purchase or an action is worth — belongs in campaigns, so marketing can change it in the Admin Panel without a release.
* **Eligibility** — who can see or redeem what — belongs in segments, tiers, labels and campaign or reward conditions.
* **Limits** — caps per member, per period or per campaign — belong in campaign and reward limits.

The integration layer should forward facts (*this member bought these items*, *this member read this article*) and let Open Loyalty decide what they are worth. A rule hard-coded in middleware is invisible in the Admin Panel, isn't covered by campaign simulation, and needs a deployment to change.

## Checklist

* [ ] One integration layer owns the API key; no key is shipped to a browser or app.
* [ ] Each channel's member identifier is mapped to the identifier Open Loyalty matches on.
* [ ] Every write that can be retried carries a stable, deterministic ID.
* [ ] Retries use exponential backoff on `429`, `5xx` and timeouts, and never retry `400` validation errors.
* [ ] Failed requests are logged with their payload.
* [ ] Webhook consumers are idempotent and tolerate out-of-order delivery.
* [ ] Earning, eligibility and limits are configured in Open Loyalty, not hard-coded.

## Further reading

* [Overview of integration methods](https://help.openloyalty.io/technical-guide/integration/overview-of-integration-methods)
* [API best practices](https://help.openloyalty.io/technical-guide/api-fundamentals/best-practices) and [limits](https://help.openloyalty.io/technical-guide/api-fundamentals/limits)
* [Environments & access](/implementation-guide/plan-and-foundations/environments-and-access.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.openloyalty.io/implementation-guide/plan-and-foundations/integration-architecture.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
