A card account on Peach is the line of credit itself. This page is about the Card objects that sit on that line of credit — the records that represent the individual cards a borrower carries. One line of credit can hold many cards, and each card can be linked to the purchases, disputes, and events it generates.
This page explains how Peach models cards. To create and manage cards through the API, see the Cards API reference. For linking purchases, see Line of credit purchases.
- How Peach models cards as first-class objects, with many cards per line of credit
- What
isExternalcontrols and why a card is external by default - What the card
statusfield is and who sets it - How
cardIdlinks a purchase or dispute to a specific card, and what happens when it can't be resolved - How to query purchases and disputes by card with the
cardIds[]filter
- Card object — A record representing a single card on a line of credit. Public id prefix
CD-. isExternal— Whether Peach interacts with the card directly. Defaults totrue(external): Peach does not interact with the card directly.status— The lender-owned card status.cardId— A validated link from a purchase or dispute to a Card object.cardIds[]— A query filter that returns only purchases or disputes linked to the given cards.
This page is decoupled from the Credit Cards guide, so it carries the few terms it needs inline. Peach's object names do not always match the industry terms a card program manager uses.
| Term | What it means on this page |
|---|---|
| Purchase | A card swipe — a charge posted to a draw. |
| Transaction | A payment against the account. Distinct from a purchase. |
| Draw | A subline of the line of credit. |
| Open to buy | Available credit — the amount the borrower can still spend. |
Card issuer (API object) (VC-) | The API object for the processor relationship. Not the Card object. |
Card object (CD-) | A record for an individual card on the line of credit. The subject of this page. |
A Card object holds a foreign key to a line of credit, and that key carries no uniqueness constraint — so a single line of credit can hold any number of cards. The line's cards collection is ordered by card id.
Each card has its own public id with the CD- prefix.
This is the multi-cardholder pattern the feature is built for: a business owner holds one line of credit and issues cards to employees, each card a Card object on the same account. Because every card can be virtual and physical, and cards are reissued over time, one line of credit can accumulate many Card objects — on the order of dozens of cardholders and several hundred card ids over a program's life.
A card carries an isExternal boolean that defaults to true. It controls whether Peach interacts with the card directly.
true(the default) — Peach does not interact with the card directly. The object exists for visualization and filtering — for example, to bucket purchases by card on a statement.false— Peach sends events to, and receives events from, the card object in another system. The lender supplies the issuer id and the issuer-specific card token or identifier (for example, a Lithic card token); Peach requires both whenisExternalisfalse.
A card carries a lender-owned status: active, inactive, blocked, closed, expired, defaulting to active. You set it and keep it current — Peach never changes it from an issuer webhook. In code it is the CardExternalStatus enum, surfaced through the serializer's external_status attribute.
A card payload also contains a separate, pre-existing internal field nested under cardDetails. The field you set and read for a card's lender-facing status is the top-level status described here.
A purchase can carry a top-level cardId that links it to a Card object. cardId accepts a Peach id, a CD- public id, or an ext- lender external id; Peach resolves whichever form you send. The card must belong to the same line of credit as the purchase — if it belongs to a different line of credit, it does not resolve.
When cardId cannot be resolved to a card on this line of credit, the request does not fail. Instead:
- Peach returns
validation.cardIdMissing: truein the response. - The link is not stored — the purchase keeps no
card_id. - The rest of the purchase is created or updated normally.
This is a soft warning, not an error. The validation block is a sibling of data at the top level of the response, and it is present only when a miss occurred. Sending cardId: null explicitly clears the link.
In responses, a resolved cardId is always returned as the Peach CD- public id, or null when no card is linked.
cardId is a new linkage; the existing purchaseDetails.externalCardId is unchanged and still fully supported. externalCardId is a free-form string in a separate column from the cardId foreign key. The two are independent: both can be set on the same purchase, neither overrides the other, and there is no precedence logic between them.
A cardIds[] query filter returns only the purchases or disputes linked to the cards you name. It is available on the four purchase list and timeline endpoints and on the two dispute list endpoints. Each value is a CD- public id or an ext- external id.
To get a per-cardholder view, pass that cardholder's card ids. To get the account-wide view of every purchase on the line of credit, omit the parameter.
An unresolvable filter returns nothing, not everything. Omitting cardIds applies no filter and returns all purchases. But sending cardIds with values that resolve to no cards returns an empty result set — not all purchases. Internally the filter becomes card_id IN (), which matches nothing; the dispute endpoints short-circuit to an empty query the same way.
The filter only matches cards linked through cardId. It matches purchases whose card_id foreign key is set. A purchase booked with only externalCardId, or booked before cardId was adopted, has a null card_id and will not appear in a cardIds[] result — a real caveat when you use this filter to bucket a statement by cardholder.
On disputes, cardId appears on the response only. It is read-only and mirrors the cardId of the disputed purchase. Dispute create and update requests do not accept cardId in the body — a dispute's card is always inherited from its purchase, never set on the dispute directly.
The linked card travels with the purchase onto its event payloads. cardId was added to these seven public purchase event payloads:
purchase.createdpurchase.changedpurchase.authorizedpurchase.settledpurchase.appliedpurchase.dispute.createdpurchase.dispute.updated
When no card is linked to the purchase, cardId is omitted entirely from the event payload — it is not sent as null.
A landscaping company holds one line of credit. The owner issues cards to five employees, and each employee carries one virtual and one physical card — so the single line of credit already holds ten Card objects, each with its own CD- public id. Lost-card reissues add more over time.
To track spending per employee, the lender records each purchase against the employee's card. When a $48.20 fuel charge posts for the employee Maria Alvarez, the lender sends cardId: "CD-7F3A-22B1" on the purchase. Peach confirms that card belongs to this line of credit and stores the link. The same cardId then rides along on the purchase.created, purchase.authorized, and purchase.settled events.
- For Maria's statement view, the lender lists purchases with
cardIds[]set to her two card ids. The result is only Maria's purchases. - For the owner's account-wide view, the lender omits
cardIds. Every purchase on the line of credit is returned.
If the lender ever sends a cardId that belongs to a different account, Peach returns validation.cardIdMissing: true, stores no link, and still records the purchase — so a mis-typed id never drops the charge.
Modeling each card as its own object — many per line of credit, external by default — lets one account carry an arbitrary number of cardholders while Peach's role stays limited to recording and reporting. The CD- Card object exists so a lender can attribute purchases, disputes, and events to a specific card without Peach issuing or processing that card. cardId makes that attribution a validated link to a real card on the same line of credit, while externalCardId remains for lenders that only need to record a free-form identifier. The result is one statement and one credit limit per account, with a per-card view available on demand.
The operations that implement everything on this page:
- Cards — Create and manage Card objects:
isExternal, the lender-ownedstatus, and Get cards (status filter and pagination). - Line of credit purchases — The
cardIdfield on purchase create and update, and thecardIdslist filter. Purchase disputes are documented in this area. - Card issuers — The card issuer object (
VC-) representing the processor relationship. - Events and Identifiers — How
cardIdappears on purchase events, and theCD-/ext-id formscardIdaccepts.