Developer Documentation

Tabsy provides a simple REST API for delivering digital receipts from your POS to shoppers in real time. One POST per transaction - receipt in the shopper vault in under 500ms.

Early access: Tabsy is onboarding its first retail partners. API keys are issued per retailer after a brief setup call. Contact us to get started.

Authentication

All API requests must include your retailer API key as a Bearer token in the Authorization header.

HTTP Header
Authorization: Bearer YOUR_API_KEY

API keys are issued privately per retailer. Each key is scoped to your account and can be rotated via the Retailer Portal. Never expose your API key in client-side code or public repositories.

Sandbox & testing

Test your integration against the live endpoint without touching a real customer. There is no separate sandbox URL - test traffic is isolated by credentials instead, so going live needs no code change.

Test API keys

Generate a test key in the Retailer Portal (Integrations page). Test keys start with tsk_test_ and go exactly where a live key goes: the Authorization: Bearer header (or X-Api-Key). Receipts sent with a test key run the exact production pipeline - validation, shopper matching, warranty and return resolution - but are flagged as tests, delivered to the shared TEST01 sandbox shopper, and excluded from your live statistics. No email or push notification is ever sent for test traffic.

TEST member codes

Any receipt addressed to a member code starting with TEST is treated as sandbox traffic, whatever channel it arrives through. On a connected POS, ring up a sale with TABSY:TEST01 as the customer note and void it afterwards - the full webhook pipeline runs end to end and the result appears in the Test receipts list in your portal.

Going live

Replace your tsk_test_ key with a live key. Same endpoint, same payload, same response format.

Test receipts still deduplicate on external_id. Prefix your test transaction ids (for example test-001) so they can never collide with real sales.

POST /pos-receipt

Submit a receipt after each transaction. The shopper is identified by their Tabsy member code, which they present at checkout via QR code or verbally.

POST https://zhnyoztnyvudmqpbikrj.supabase.co/functions/v1/pos-receipt

Content type

Content-Type: application/json

Request payload schema

FieldTypeRequiredDescription
member_codestringYesShopper's Tabsy member code (6-char alphanumeric)
store_namestringYesYour store or branch name as registered with Tabsy
transaction_atstring (ISO 8601)YesTransaction datetime in UTC, e.g. 2026-05-05T14:32:00Z
currencystring (ISO 4217)YesThree-letter currency code, e.g. AED, EUR, GBP
totalnumberYesTransaction total as a decimal number
itemsarrayYesArray of line items (see item schema below)
return_window_daysintegerNoNumber of days the shopper has to return items (default: none)
external_idstringNoYour internal transaction or receipt ID for deduplication
notesstringNoAny free-text note attached to the receipt

Item schema

FieldTypeRequiredDescription
namestringYesProduct name
pricenumberYesUnit price
qtyintegerNoQuantity (default: 1)
skustringNoYour internal SKU or product code
warranty_monthsintegerNoManufacturer warranty period in months
categorystringNoProduct category for analytics

Example request

POST /functions/v1/pos-receipt
// Headers: Authorization: Bearer YOUR_API_KEY
//          Content-Type: application/json

{
  "member_code":       "A7K2M9",
  "store_name":         "IKEA Dubai Marina",
  "transaction_at":     "2026-05-05T14:32:00Z",
  "currency":           "AED",
  "total":              329.00,
  "return_window_days": 14,
  "external_id":        "POS-20260505-0042",
  "items": [
    {
      "name":             "BILLY Bookcase",
      "price":            199.00,
      "qty":              1,
      "sku":              "BILLY-202X-WHT",
      "warranty_months":  24,
      "category":         "Furniture"
    },
    {
      "name":             "KALLAX Shelf Unit",
      "price":            130.00,
      "qty":              1
    }
  ]
}

Response

Success (200 OK)

JSON Response
{
  "status": "inserted",
  "receipt_id": "rcpt_01jx3k2m...",
  "delivery": "delivered"
}

Error codes

HTTP statusMeaningAction
401 UnauthorizedMissing or invalid API keyCheck your Authorization header and key value
403 ForbiddenAPI key valid but not authorised for this storeContact support to verify your key-store binding
422 Unprocessable EntityPayload validation failedCheck required fields and data types. Response body contains field-level errors.
429 Too Many RequestsRate limit exceededBack off and retry after the Retry-After header value (seconds)
500 Internal Server ErrorServer-side errorRetry with exponential backoff. If persistent, contact support.

Rate limits

The API enforces rate limits per API key to protect infrastructure quality:

  • Default limit: 300 requests per minute per API key
  • Burst limit: Up to 60 requests per second for short bursts
  • Enterprise: Higher limits available - contact us for high-volume configurations

When a rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait before retrying.

Webhook retry behaviour

Tabsy processes receipts asynchronously after initial acceptance. If delivery to the shopper fails, the system retries automatically:

  • Retry schedule: 5 attempts over 24 hours (1min, 5min, 30min, 4hr, 20hr)
  • Delivery status: Track delivery outcomes in your Retailer Portal under the Receipts tab
  • Shopper not found: If no Tabsy account matches the member code, the receipt is held for 30 days in case the shopper registers later
  • Idempotency: Use the external_id field to prevent duplicate receipts - the same external_id submitted twice returns the original receipt
Need help? Email contact@tabsyapp.com or request integration - we'll walk you through setup and answer technical questions.