API Reference

Integrationsendpunkte

Die Datenendpunkte, die ein verbundener Partner mit seinem Zugriffstoken aufruft.

Authenticating Requests

Once a partner has completed the OAuth flow and exchanged its integration token, it holds an access token scoped to a single connected store. Every Partner Endpoint is authorised with that token.

How to authenticate

Pass the access token as the access_token query parameter:

http
POST /v1/orders?access_token={accessToken}

The access token identifies the connected store; you do not send client_id/client_secret on these data endpoints (those are only used in the OAuth flow and for token refresh).

Token validity

  • Access tokens are valid for 1 year.
  • Refresh ahead of expiry with POST /v1/auth/token (see Tokens & lifecycle).
  • A missing, expired, or revoked token returns 403.

What the token can do

An access token grants the connected store the ability to:

CapabilityEndpoint
Update the store profilePUT /v1/stores
Read store settings (e-receipts on/off)GET /v1/stores
Get an upload URL for the customers listGET /v1/customers
Send an order / transactionPOST /v1/orders
Read an order (for e-receipts)GET /v1/orders

Each is documented in the following sections. All endpoints are served under the /v1 base path.

Conventions

  • Money is expressed in the minor unit of the currency (e.g. cents) as a string, with an ISO

currency code (e.g. "USD").

  • Timestamps are ISO-8601 (e.g. 2026-06-28T14:03:00.000Z).
  • Content type for request bodies is application/json.

Update Store Profile

Create or update the profile of the connected store — its name, address, contact details and currency. Keeping this current improves ad localisation and receipt accuracy.

http
PUT /v1/stores?access_token={accessToken}
Content-Type: application/json

Request body

FieldTypeRequiredDescription
storeNamestringyesDisplay name of the store.
storeAddressstringyesStreet address line.
storeCountryCodestringyesISO country code (e.g. US).
storeCitystringnoCity.
storeStatestringnoState / region.
storePostalCodestringnoPostal / ZIP code.
storePhoneNumberstringnoPublic contact number.
storeCurrencystringnoISO currency code (e.g. USD). Defaults to the store's configured currency.
json
{
  "storeName": "Bridge Street Bakery",
  "storeAddress": "120 Bridge Street",
  "storeCity": "Austin",
  "storeState": "TX",
  "storeCountryCode": "US",
  "storePostalCode": "78701",
  "storePhoneNumber": "+1-512-555-0142",
  "storeCurrency": "USD"
}

Response 200

json
{
  "store": {
    "id": "…",
    "name": "Bridge Street Bakery",
    "phoneNumber": "+1-512-555-0142",
    "address": {
      "addressLine": "120 Bridge Street",
      "city": "Austin",
      "state": "TX",
      "country": "US",
      "postalCode": "78701"
    },
    "currency": "USD"
  }
}

Errors

StatusMeaning
400A request field is missing or invalid.
403access_token is missing, expired, or invalid.
500Unexpected server error.

See Errors for the shared error model.

Send Customers List

Send the store's customer list so Rulrr can build targeted and look-alike audiences for campaigns. This is the foundation of initial targeting: the better the customer data, the stronger the audiences Rulrr can create on the ad networks.

Because customer lists can be large, the upload is a two-step, pre-signed URL process — you never post the list to the API directly.

Step 1 — Request an upload URL

http
GET /v1/customers?access_token={accessToken}

Response 200

json
{ "uploadUrl": "https://…s3…/customers/…?X-Amz-Signature=…" }

The uploadUrl is a short-lived, pre-signed URL that accepts a single file upload.

Step 2 — Upload the customers file

PUT the customer records as JSON to the uploadUrl returned above. Each record should contain whatever identifiers you have; email and phone are the most valuable for matching.

json
[
  {
    "firstName": "Dana",
    "lastName": "Levy",
    "email": "dana@example.com",
    "phoneNumber": "+15125550101",
    "city": "Austin",
    "countryCode": "US"
  },
  {
    "firstName": "Sam",
    "lastName": "Cohen",
    "email": "sam@example.com",
    "phoneNumber": "+15125550102"
  }
]

Rulrr ingests the file, de-duplicates customers (by email, falling back to phone), and uses the result to seed audiences. Re-send the list periodically to keep audiences fresh; ingestion is idempotent, so re-uploading the same customers will not create duplicates.

Field guidance

FieldRecommendedNotes
emailstronglyPrimary match key.
phoneNumberstronglyFallback match key; E.164 format preferred.
firstName, lastNameyesImproves match quality and personalisation.
city, countryCodeoptionalHelps geo-targeting.

Errors

StatusMeaning
403access_token is missing, expired, or invalid.
400Invalid request.
500Unexpected server error.
Privacy. Only send customer data you are permitted to share for advertising. Rulrr uses it to create and measure audiences on the merchant's behalf.

Send Orders (Transactions)

Send each completed order (transaction) so Rulrr can measure conversions and attribute revenue to campaigns. This is how the merchant sees real sales impact — and how Rulrr distinguishes new vs. returning customers.

http
POST /v1/orders?access_token={accessToken}
Content-Type: application/json

Request body

FieldTypeRequiredDescription
orderIdstringyesYour unique ID for the order. Re-sending the same orderId updates the existing order.
orderPricestringyesTotal in the currency's minor unit (e.g. cents).
orderCurrencystringyesISO currency code (e.g. USD).
createdAtstringyesISO-8601 timestamp of the order.
updatedAtstringnoISO-8601 timestamp of the last change.
customerFirstNamestringnoCustomer first name.
customerLastNamestringnoCustomer last name.
customerPhoneNumberstringnoCustomer phone (enables SMS e-receipts).
customerEmailstringnoCustomer email.
orderDetailsobjectnoPass-through detail: status, type, line items, payments (see below).
storeobjectnoStore snapshot (same fields as Update Store Profile); lets you create/update the store inline.
json
{
  "orderId": "POS-10293",
  "orderPrice": "4200",
  "orderCurrency": "USD",
  "createdAt": "2026-06-28T14:03:00.000Z",
  "customerFirstName": "Dana",
  "customerLastName": "Levy",
  "customerPhoneNumber": "+15125550101",
  "customerEmail": "dana@example.com",
  "orderDetails": {
    "orderStatus": "CLOSED",
    "orderType": "dine-in",
    "orderItems": [
      { "itemId": "SKU-1", "itemName": "Sourdough", "itemPrice": "1200", "itemQuantity": 2, "itemTax": "0" }
    ],
    "orderPayments": [
      { "paymentType": "card", "paymentId": "pay_1", "paymentSum": "4200", "paymentCardType": "visa", "paymentLast4": "4242" }
    ]
  }
}

What Rulrr does with an order

  1. Resolves the customer from the provided name/email/phone (creating or updating the consumer

record), so the order is tied to a person.

  1. Records the order against the store, classifying the conversion as new, returning,

organic, or anonymous — this powers conversion stats and revenue attribution.

  1. Optionally triggers an e-receipt by SMS when e-receipts are enabled and the order is CLOSED

with a customer phone number (see E-receipts).

Response 200

json
{ "statusCode": 200 }

Errors

StatusMeaning
400A required field is missing or invalid.
403access_token is missing, expired, or invalid.
500Unexpected server error.
Send orders continuously. Streaming every closed transaction (not just a daily batch) gives the most accurate, near-real-time conversion measurement.

E-Receipts & Store Settings

Some integrations offer e-receipts — an SMS receipt sent to the customer at checkout. E-receipts both delight customers and strengthen Rulrr's customer/consent data. This section covers reading the store's settings and the e-receipt read endpoint.

Read store settings

Check whether e-receipts are enabled for the connected store.

http
GET /v1/stores?access_token={accessToken}

Response 200

json
{ "greenInvoices": true }

greenInvoices reflects the e-receipt preference the merchant chose on the Rulrr-Connect screen. When true, the integration should offer the e-receipt step at the point of sale.

How e-receipts are sent

E-receipts are triggered automatically by Rulrr when all of the following hold for an order sent via POST /v1/orders:

  • the store has e-receipts enabled (greenInvoices: true), and
  • the order's orderDetails.orderStatus is CLOSED, and
  • the order includes a customer phone number.

When triggered, Rulrr sends the customer an SMS linking to a hosted receipt at https://connect.rulrr.com/inv/{orderId}.

Point-of-sale prompt (optional)

If your terminal supports it, prompt the cashier for the customer's phone number at checkout so the e-receipt can be sent. If the customer opts in and enters a valid number, you can dismiss the printed receipt in favour of the SMS one.

Read an order (hosted receipt)

The hosted receipt page reads the order via:

http
GET /v1/orders?orderId={orderId}

This returns the order with its line items, payments and store snapshot for display. It is gated: the store must have e-receipts enabled, the order must be CLOSED, and the order must have an associated customer with a phone number — otherwise it returns 403/404.

Most partners never call GET /v1/orders directly; it backs the hosted e-receipt page. It is documented here for completeness.

Errors

Integration Endpoints use standard HTTP status codes. A non-2xx response indicates the request was not applied.

StatusMeaningTypical cause
200SuccessThe request was accepted and applied.
400Bad requestA required field or parameter is missing or malformed.
403Forbiddenaccess_token is missing, expired, revoked, or invalid — or the resource is not enabled for this store (e.g. e-receipts off).
404Not foundThe referenced resource (e.g. an order) does not exist or is not visible.
410GoneA one-time resource was already consumed — e.g. integration tokens can only be exchanged once.
500Server errorUnexpected error on Rulrr's side; safe to retry with backoff.

Handling guidance

  • 400 — fix the request; do not retry unchanged. Validate required fields and money/timestamp

formats (minor units as strings; ISO-8601 timestamps).

the integration may have been revoked — re-run the OAuth flow.

  • 404 / 410 — the resource is missing or already used; do not retry blindly.
  • 500 — retry with exponential backoff. If it persists, contact

Developer Support.

Idempotency

  • Orders are keyed by your orderId — re-sending the same orderId updates the existing order

rather than creating a duplicate, so retries are safe.

  • Customer uploads are de-duplicated on ingest (by email, then phone), so re-uploading is safe.