Using the Transactions API (POS + OMS unified feed)

API OAuth Transactions POS OMS Android iOS

Purpose of this guide

ReceiptRoller's Transactions API is a read-only endpoint that unifies register sales (POS transactions) and order-management orders (OMS) into a single feed. It covers the use case "I want to see all of a business account's transactions on one screen".

Why is this a separate endpoint?

  • The Sales API aggregates POS transactions and returns KPIs / graphs
  • The Orders API provides CRUD on OMS orders
  • Each of those sees only one side. When you need "a transaction list across all channels", use this API

Note: The Transactions API is read-only. Perform writes via the Orders API (OMS) or through each POS integration.

Endpoint

GET /api/v1/transactions
  ?organizationId={organizationId}
  &storeId={storeId}                 (optional, filter by store)
  &since=2026-05-01T00:00:00Z        (optional, default: 30 days ago)
  &until=2026-06-01T00:00:00Z        (optional, default: now)
  &source=all|pos|oms                (optional, default: all)
  &page=1
  &pageSize=100                      (max 500)
Authorization: Bearer {access_token}

Required scope: either store.orders.read or sales.read.

Response example

{
  "organizationId": "a04507de-043a-4b47-b0a3-6204562f6e20",
  "window": {
    "since": "2026-05-01T00:00:00Z",
    "until": "2026-06-01T00:00:00Z"
  },
  "transactions": [
    {
      "id": "pos:term-001:tx-9001",
      "source": "pos",
      "occurredAt": "2026-05-31T18:22:14Z",
      "storeId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "channel": "POS",
      "status": "Completed",
      "amounts": { "subtotal": 960, "tax": 96, "shipping": 0, "discount": 0, "total": 1056 },
      "itemCount": 2,
      "customer": null,
      "links": {
        "posTransactionId": "tx-9001",
        "posTerminalId": "term-001",
        "omsOrderId": null
      }
    },
    {
      "id": "oms:ord-001",
      "source": "oms",
      "occurredAt": "2026-05-31T09:10:00Z",
      "storeId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "channel": "Web",
      "status": "Delivered",
      "amounts": { "subtotal": 1140, "tax": 114, "shipping": 500, "discount": 0, "total": 1754 },
      "itemCount": 3,
      "customer": { "name": "Hanako Sato", "email": "hanako@example.com" },
      "links": {
        "posTransactionId": null,
        "posTerminalId": null,
        "omsOrderId": "ord-001"
      }
    }
  ],
  "page": 1,
  "pageSize": 100,
  "totalCount": 247,
  "totalPages": 3
}

How to read the fields

  • source"pos" or "oms". Indicates which world the transaction came from
  • occurredAt — for POS, the transaction date/time; for OMS, the creation date/time. The two are interleaved and sorted DESC
  • channel — POS is always "POS". OMS is Web / Phone / Manual / Marketplace, etc.
  • status — POS is Completed / Voided. OMS is Pending / Confirmed / Processing / Shipped / Delivered / Cancelled / Refunded
  • customer — null for POS; for OMS, the name and email if entered
  • links — the IDs to use when you want to drill down for details. POS rows embed posTransactionId + posTerminalId; OMS rows embed omsOrderId

Limitations

  • The retrieval window is at most 365 days. Exceeding it returns 400 Bad Request
  • At most 5,000 records per source are fetched internally and merged. For tenants with long windows or high transaction volume that exceed this, narrow the range with since / until
  • At most 500 records per page
  • Linking POS and OMS (for example, picking up an online order at the store counter) is not yet supported. This is planned for release in t-e9a2f470 (Phase 2)

The premise that POS and OMS are separate worlds

In the current ReceiptRoller:

  • Register sales on a POS (Square / Smaregi / Airregi, etc.) → written to PosTransactions only
  • Web orders / phone orders / marketplace → written to OmsOrders only
  • POS and OMS are currently not linked. Even though they are transactions of the same business, they are recorded split across two places

This API virtually unifies that split at the API layer. Unification at the data layer is planned for future phases:

  • Phase 2 (t-e9a2f470): link store pickup of online orders via OmsOrder.LinkedPosTransactionId
  • Phase 3 (t-e9a2f471, t-e9a2f472): also auto-materialize POS transactions into OMS. Analytics unified onto an OMS base as well

Typical flow (mobile app)

  1. Obtain an access token via OAuth → include store.orders.read or sales.read in the scopes
  2. Select a business account with GET /api/v1/me/organizations
  3. On the transaction list screen, call GET /api/v1/transactions?since=...&pageSize=50 and advance page with infinite scroll
  4. Switch the POS icon / OMS icon per row based on source
  5. When a row is tapped, look at links and drill down: for a POS row, to /api/v1/sales/products or the Sales API; for an OMS row, to GET /api/v1/orders/{omsOrderId}

Error responses

StatusMeaningWhat to do
401 UnauthorizedAccess token invalid / expiredRefresh
403 ForbiddenNo scope / not a member of the business accountCheck the scope
400 Bad RequestWindow exceeds 365 days / until <= since / invalid source valueReview the parameters

Related information

Published: 2026-06-01 Updated: 2026-07-05
このトピックについて
開発者API
機能の詳細を見る
Tags
API (22) OAuth (15) Android (10) iOS (9) Webhook (6) Troubleshooting (5) api (5) App registration (4) POS Integration (4) Reference (4)
Related articles