Skip to main content
Offers are the catalog of experiences a member can redeem. listOffers returns the offers available to the calling member, each with its points price and optional expiry, paged with a cursor.
These are member-mode calls: they use the member token, not the Org-API-Key. See Authentication. Whether you read the sandbox demo catalog or your live catalog is selected by the key the token was minted from - see Environments.

List offers

listOffers(limit?, cursor?) calls GET /v1/offers and returns an OfferList. The snippet below pages through the entire catalog by following nextCursor until it comes back null:
import { initialize } from "@expys/sdk";

const token = process.env.EXPYS_MEMBER_TOKEN;
if (!token) {
  throw new Error(
    "Set EXPYS_MEMBER_TOKEN (a member token from your backend's /v1/auth/exchange)",
  );
}

const expys = initialize({
  baseUrl: process.env.EXPYS_BASE_URL,
  environment: "sandbox",
  token,
});

async function main(): Promise<void> {
  let cursor: string | undefined;
  let page = 0;
  let total = 0;

  // Loop until the server returns a null nextCursor, marking the end of the list.
  do {
    const result = await expys.listOffers({ cursor, limit: 50 });
    page += 1;
    total += result.data.length;
    console.log(`page ${page}: ${result.data.length} offers`);
    cursor = result.nextCursor ?? undefined;
  } while (cursor);

  console.log(`done: ${total} offers across ${page} page(s)`);
}
curl
curl https://api.expys.com/v1/offers?limit=50 \
  -H "Authorization: Bearer YOUR_MEMBER_TOKEN"

The Offer schema

Each entry in data is an Offer:
FieldTypeDescription
idstringStable offer id. Pass it as offer to create a redemption.
titlestringDisplay title of the offer.
descriptionstringFull description.
shortDescriptionstringA condensed description for list views and cards.
kindstringThe offer kind.
typestringThe offer type.
pointsPriceinteger | nullPoints debited on redemption. null means no points cost (free).
expiresAtstring | nullISO-8601 expiry. null means the offer does not expire.
pointsPrice of null is distinct from 0: it means the offer carries no points price at all. An offer past its expiresAt is no longer redeemable - attempting to redeem it returns OFFER_UNAVAILABLE. See Redemptions.

Pagination

OfferList is cursor-paginated:
FieldTypeDescription
dataOffer[]The offers on this page.
nextCursorstring | nullPass back as cursor to fetch the next page. null when there are no more.
ParameterTypeDescription
limitintegerMaximum number of offers to return on a page.
cursorstringThe nextCursor from the previous page. Omit on the first call.
Pagination is cursor-based, not page-numbered. Pass the previous response’s nextCursor as the next request’s cursor, and stop when nextCursor is null. Do not assume a fixed page size or construct cursors yourself - treat the cursor as an opaque token.

Next steps

Redemptions

Redeem an offer, spend points, and follow the redemption lifecycle.

Points and wallet

How points are minted, spent, and tracked against pointsPrice.

API reference

The full GET /v1/offers schema and an interactive playground.