REST API Reference

Read-only JSON over HTTPS · Subscriptions, customers and orders

1. Basics

ItemValue
Base URLhttps://app.sublyra.com/api/v1
AuthenticationAuthorization: Bearer cad_pk_… — an API key from Settings → Integrations. See Authentication.
MethodsGET only. Everything else returns 405.
Response formatJSON, always — including errors. Success: { "data": [ … ], "page": { … } }.
MoneyInteger cents in the shop's currency (totalCents: 4200 = $42.00).
DatesISO 8601 UTC strings; unset dates are null.

The API serves Sublyra's local mirror of your subscription data — Shopify remains the source of truth, and inbound Shopify webhooks keep the mirror in step. Reads are fast, consistent and never rate-limited by Shopify's own API.

Plan availability. API access requires the Pro plan, or the API & webhooks add-on ($19.99/mo). Keys can only be created on an eligible plan.

2. Pagination

All three endpoints share the same cursor pagination:

ParameterDefaultNotes
limit50Maximum 250. Non-numeric or non-positive values fall back to the default.
cursor—The nextCursor value from the previous page, passed verbatim. Opaque — don't build one yourself.

Every response carries a page object:

{
  "data": [ … ],
  "page": {
    "limit": 50,
    "nextCursor": "2026-08-01T12:00:00.000Z~clx9k2m4p0001…"
  }
}

When nextCursor is null, you're on the last page. When it's a string, pass it back as ?cursor= to get the next page:

curl "https://app.sublyra.com/api/v1/subscriptions?limit=250&cursor=2026-08-01T12%3A00%3A00.000Z~clx9k2m4p0001" \
  -H "Authorization: Bearer cad_pk_your_key_here"

Pages are ordered newest-first by each resource's date field (startedAt for subscriptions, createdAt for customers, billedAt for orders). The cursor is compound — <ISO date>~<id> — so rows that share a timestamp are never skipped or duplicated between pages.

Pass cursors verbatim. A hand-edited or truncated cursor returns 400 bad_cursor. URL-encode it when building query strings (the ~ and : characters need it in some clients).

3. GET /api/v1/subscriptions

Lists your subscription contracts, newest startedAt first.

curl "https://app.sublyra.com/api/v1/subscriptions?limit=50" \
  -H "Authorization: Bearer cad_pk_your_key_here"

Response

{
  "data": [
    {
      "id": "clx9k2m4p0001abcd",
      "shopifyId": "gid://shopify/SubscriptionContract/1001",
      "customerId": "clx9k2m4p0002efgh",
      "status": "ACTIVE",
      "interval": "MONTH",
      "intervalCount": 1,
      "sellingPlanId": "gid://shopify/SellingPlan/2001",
      "lines": [
        {
          "variantId": "gid://shopify/ProductVariant/3001",
          "productId": "gid://shopify/Product/4001",
          "title": "House Blend — 1kg",
          "quantity": 2,
          "unitPriceCents": 2100
        }
      ],
      "nextBillingDate": "2026-09-01T00:00:00.000Z",
      "cyclesCompleted": 3,
      "startedAt": "2026-06-01T09:30:00.000Z",
      "cancelledAt": null
    }
  ],
  "page": { "limit": 50, "nextCursor": null }
}

Fields

FieldTypeNotes
idstringSublyra's internal contract ID. Stable — use it to join with contractId on orders.
shopifyIdstringThe Shopify subscription contract gid.
customerIdstringInternal customer ID — matches id from /api/v1/customers.
statusstringACTIVE · PAUSED · CANCELLED · PAYMENT_FAILED · EXPIRED
intervalstringDAY · WEEK · MONTH
intervalCountnumberHow many intervals between billings — interval: MONTH, intervalCount: 2 bills every two months.
sellingPlanIdstring | nullThe Shopify selling plan gid the contract belongs to.
linesarrayLine-item snapshot: variantId, productId, title, quantity, unitPriceCents.
nextBillingDatestring | nullISO date of the next scheduled billing; null for cancelled/expired contracts.
cyclesCompletednumberRenewals billed so far.
startedAtstringISO date the contract started. The sort field for this endpoint.
cancelledAtstring | nullISO date of cancellation, if any.

4. GET /api/v1/customers

Lists customers known to Sublyra — your subscribers and their loyalty state — newest createdAt first.

curl "https://app.sublyra.com/api/v1/customers?limit=50" \
  -H "Authorization: Bearer cad_pk_your_key_here"

Response

{
  "data": [
    {
      "id": "clx9k2m4p0002efgh",
      "shopifyId": "gid://shopify/Customer/5001",
      "email": "jane@example.com",
      "firstName": "Jane",
      "lastName": "Doe",
      "marketingConsent": true,
      "creditsCents": 750,
      "loyaltyTier": 1,
      "subscriptionCount": 2,
      "createdAt": "2026-06-01T09:28:00.000Z"
    }
  ],
  "page": { "limit": 50, "nextCursor": null }
}

Fields

FieldTypeNotes
idstringInternal customer ID — the value customerId refers to on subscriptions and orders.
shopifyIdstringThe Shopify customer gid.
email, firstName, lastNamestring | nullFrom the Shopify customer record.
marketingConsentbooleanWhether the customer opted in to marketing. Transactional mail ignores this; marketing features respect it.
creditsCentsnumberCurrent loyalty store-credit balance, in cents.
loyaltyTiernumberTier index — 0 is the base tier.
subscriptionCountnumberHow many contracts (any status) this customer has.
createdAtstringISO date the customer record was first mirrored. The sort field for this endpoint.

5. GET /api/v1/orders

Lists subscription orders — both checkout (first) orders and recurring renewals — newest billedAt first.

curl "https://app.sublyra.com/api/v1/orders?limit=50" \
  -H "Authorization: Bearer cad_pk_your_key_here"

Response

{
  "data": [
    {
      "id": "clx9k2m4p0003ijkl",
      "shopifyId": "gid://shopify/Order/6001",
      "contractId": "clx9k2m4p0001abcd",
      "customerId": "clx9k2m4p0002efgh",
      "source": "recurring",
      "cycleNumber": 3,
      "status": "PAID",
      "lines": [
        {
          "variantId": "gid://shopify/ProductVariant/3001",
          "productId": "gid://shopify/Product/4001",
          "title": "House Blend — 1kg",
          "quantity": 2,
          "unitPriceCents": 2100
        }
      ],
      "subtotalCents": 4200,
      "discountCents": 420,
      "creditsCents": 0,
      "totalCents": 3780,
      "billedAt": "2026-08-01T00:01:00.000Z"
    }
  ],
  "page": { "limit": 50, "nextCursor": null }
}

Fields

FieldTypeNotes
idstringInternal order ID.
shopifyIdstring | nullThe Shopify order gid. null until the charge succeeds — a failed attempt has no Shopify order yet.
contractIdstringInternal contract ID — matches id from /api/v1/subscriptions.
customerIdstringInternal customer ID.
sourcestringcheckout (the subscriber's first order) · recurring (a renewal).
cycleNumbernumberWhich renewal this is for the contract — 1 is the first.
statusstringPENDING · PAID · RECOVERED · FAILED · UNCOLLECTIBLE · SKIPPED
linesarrayLine-item snapshot, same shape as contract lines.
subtotalCentsnumberLine total before discounts and credits.
discountCentsnumberDiscounts applied to this order.
creditsCentsnumberLoyalty store credit applied to this order.
totalCentsnumberWhat was (or will be) charged: subtotal − discount − credits.
billedAtstringISO date of the billing attempt. The sort field for this endpoint.

6. Errors

Every error — including unexpected server failures — is JSON with a stable, machine-readable code:

{
  "error": {
    "code": "bad_cursor",
    "message": "Malformed cursor. Pass the nextCursor value from the previous page verbatim."
  }
}
StatusCodeMeaning → fix
400bad_cursorThe cursor parameter isn't a cursor this API issued → pass the previous page's nextCursor verbatim, URL-encoded.
401unauthorizedMissing/malformed header, or an unknown key → see Authentication errors. Responses include WWW-Authenticate: Bearer.
404not_foundUnknown resource path → the available resources are subscriptions, customers, orders.
405method_not_allowedAnything but GET → the public API is read-only. Responses include Allow: GET.
500internalUnexpected server error → safe to retry; if it persists, contact support.

7. Read-only by design

The public API has no write surface at all — there is no POST to create a contract and no DELETE to cancel one. That's deliberate:

To react to changes instead of polling, subscribe to outbound webhooks; to automate inside Shopify, use the Flow triggers.