PackflipPartner

Core concepts

Environments, balance, customers, cards, and operations.

Environments

EnvironmentBase URLNetworkMoney
Productionhttps://partner.packflip.xyzBaseReal USDC and real cards
Sandboxhttps://sandbox.partner.packflip.xyzBase SepoliaTest credit and a synthetic catalog

Both environments run the same API and share one console login, so an organization exists in both. Everything else is separate: API keys, balances, customers, cards, and webhook endpoints. A sandbox key does not work in production, and the reverse.

Account and organization

Your Partner account is an organization in the console. Every API key acts for the whole organization, and every request is scoped to it. There is no partner ID in URLs: the key identifies the account.

GET /api/v2/account returns the account, including its public ID (par_…).

Balance and ledger

Operations are paid from a prepaid USD balance with two buckets:

  • cash: value you funded, plus buyback credits.
  • bonus: promotional value granted by Packflip. It is spent before cash.

A refund returns value to the bucket it was spent from.

GET /api/v2/balance returns cash, bonus, and total. Every change is an immutable entry in the ledger (GET /api/v2/ledger-entries), with a kind of TOPUP, BONUS, BUYBACK, SPEND, or ADJUSTMENT.

All money values are decimal strings with six places, such as "25.000000". Parse them with a decimal type, never as floating-point numbers.

Catalog

A vending machine (GET /api/v2/vending-machines) is a pack with a fixed priceUsd. Each draw selects a card at random according to the machine's published odds and stock.

Each machine has three image fields:

  • image: the pack artwork, possibly animated. Show this one.
  • imageSrcset: the same artwork at 256, 512, and 1024 pixels wide, for srcset. null when resizing is unavailable.
  • staticImage: a still frame for first paint, for example as a placeholder while image loads or where animation is unwanted. It can be an empty string; fall back to image.

Customers

A customer (cus_…) is one of your end users as Packflip sees them: a pseudonymous identity that cards and operations attach to. Packflip uses customers to understand purchase behaviour across packs, and they will power the reports you see in the console.

  • externalUserId is optional. Set it to your own user ID when your customers map to users, then find a customer with GET /api/v2/customers/by-external-id/{externalUserId}. Once set, it cannot be moved to another customer. Leave it out when that does not fit your product, for example when cards go to randomly chosen winners.
  • attributes is an optional JSON object of analytics properties, such as { "plan": "pro", "country": "JP", "channel": "campaign-2026-09" }. Updates merge into the stored object, and a key set to null is removed. Limits: 50 keys, values nested at most two levels, 8 KB in total, and keys may not start with $.

Customers hold no contact details and no wallets. Shipping details are sent with each redemption, and the destination wallet with each mint. Do not put names, email addresses, or other directly identifying data in attributes.

curl -X PATCH "$PACKFLIP_BASE_URL/api/v2/customers/cus_…" \
  -H "Authorization: Bearer $PACKFLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "attributes": { "plan": "pro", "trial": null } }'

Cards

A card (card_…) is a real graded collectible, held by Packflip for the customer until they decide what to do with it.

StatusMeaning
activeOwned by the customer: held by Packflip, or minted to their wallet.
reservedLegacy state for cards drawn before they were minted. New integrations do not create it.
buyback_pendingA minted card waiting for its on-chain burn.
bought_backSold back to Packflip.
redeemedShipped, or being shipped, to the customer.
refundedA sealed card that was refunded.
cancelledThe draw was cancelled and the card returned to stock (legacy draw-and-mint orders only).

A card also has:

  • sealed: true while the card is hidden. Its name, image, buybackUsd, and metadata are null until it is revealed.
  • onchain: set once a mint is authorized. onchain.mintedAt stays null until the mint transaction confirms.
  • buybackUsd: the current market buyback value. It changes over time; it is not a quote.

What you can do with a card

Every action needs status to be active. The other two fields decide the rest:

sealedonchainStateAllowed actions
truenullSealedReveal; refund until refundableUntil
falsenullHeldOff-chain buyback, redemption, mint
falseset, mintedAt is nullMint pendingSubmit or cancel the mint (see On-chain cards)
falseset, mintedAt is setMintedOn-chain buyback

A card is held, and eligible for off-chain buyback and redemption, exactly when status is active, sealed is false, and onchain is null. A cancelled or expired mint clears onchain, so the card is held again. Any other state returns 409 conflict for the off-chain actions.

Operations

Every change to cards or balance is an operation (op_…), created with POST /api/v2/operations:

kindmodeWhat it does
orderoffchainDraws cards and charges the pack price.
refundoffchainRefunds sealed cards within their refund window.
buybackoffchainBuys back held cards and credits their value.
buybackonchainBuys back minted cards once their NFTs are burned.
redemptionoffchainShips held cards to the customer and charges shipping.
mintonchainWithdraws held cards as NFTs to the customer's wallet.

An operation's status is pending, awaiting_chain, completed, failed, or cancelled. Off-chain operations complete within the request. On-chain operations return awaiting_chain until the transactions confirm. See On-chain cards.