Cards & Cardholders

Who holds a card, what it's issued from, and how it can be used.

Issuing a card involves three things working together: a Cardholder (who the card belongs to), a Card Product (the template it’s issued from), and the Card itself.

Cardholders

A cardholder is a person or a business you’re issuing cards to:

  • Individual — a natural person, identified by name, email, and address
  • Corporate — a business, for cards issued to an organization rather than a person

Create one with POST /cardholders/individual or POST /cardholders/corporate. Requests take an optional phone_number and an address with line_1, line_2 (optional), city, state_or_province (an ISO 3166-2 code such as CA, required for countries that use subdivisions), post_code, and country (ISO 3166-1 alpha-2). In responses, the phone number is returned as phone and the postal code as zip_code.

Cardholder PII — given_name, family_name, email, phone, and the address line_1, line_2, and zip_code — is masked by default everywhere a single cardholder is returned (create, get, update, activate, deactivate, terminate, and history). Pass ?reveal_sensitive=true to get the real values back:

GET /cardholders/{cardholder_id} (default, masked)
{
"cardholder_id": "cardholder_01937e19-4ebb-75bd-8250-4ebb5bd25085",
"version": 1,
"version_time": "2026-01-15T18:32:00Z",
"business_id": "business_01937b95-484e-75af-8c68-484e5afc68d3",
"business_entity_id": "business_entity_01937c9d-3a1e-72b0-8881-3a1e2b088159",
"program_id": "program_019377de-7f88-7f02-894f-7f88f0294fcb",
"status": "active",
"active": true,
"address": {
"line_1": "**********",
"line_2": "**********",
"city": "San Francisco",
"state_or_province": "CA",
"zip_code": "**********",
"country": "US"
},
"email": "**********",
"phone": "**********",
"type": "individual",
"given_name": "**********",
"family_name": "**********"
}
GET /cardholders/{cardholder_id}?reveal_sensitive=true
{
"cardholder_id": "cardholder_01937e19-4ebb-75bd-8250-4ebb5bd25085",
"version": 1,
"version_time": "2026-01-15T18:32:00Z",
"business_id": "business_01937b95-484e-75af-8c68-484e5afc68d3",
"business_entity_id": "business_entity_01937c9d-3a1e-72b0-8881-3a1e2b088159",
"program_id": "program_019377de-7f88-7f02-894f-7f88f0294fcb",
"status": "active",
"active": true,
"address": {
"line_1": "1 Market St",
"line_2": "Suite 400",
"city": "San Francisco",
"state_or_province": "CA",
"zip_code": "94105",
"country": "US"
},
"email": "jordan.rivera@acme.example",
"phone": "+15551234567",
"type": "individual",
"given_name": "Jordan",
"family_name": "Rivera"
}

GET /cardholders/ (list) doesn’t accept reveal_sensitive: list results are always masked, so cardholder PII can’t be read in bulk. Fetch a cardholder individually with reveal_sensitive=true when you need the real values.

A cardholder moves between active, deactivated, and suspended. Terminating a cardholder (DELETE /cardholders/{cardholder_id}) moves it to deleting and then deleted, which is permanent.

You can attach a Spend Control directly to a cardholder so it applies across every card they hold. Assign or replace it with PUT /cardholders/{cardholder_id}/spend_control (body {"spend_control_id": "..."}) and remove it with DELETE /cardholders/{cardholder_id}/spend_control, both on the Issuing API.

Card Products

A Card Product is the template a card is issued from. It determines the card’s form factor, its usage type, how its expiration date is set, and which BINs and BIN ranges it can be issued under. Card products are configured for your business by Penny; list the ones available to you:

GET /products/
GET /products/{card_product_id}

Penny chooses the BIN and BIN range for each card from the product’s configuration. The card’s bin_id and bin_range_id show which were used.

BINs and BIN ranges

A BIN (Bank Identification Number) is the first digits of a card number (6–8 digits); it identifies the card’s issuer and network. A BIN range is a sub-range of card numbers within a BIN, with its own currency and its own capabilities: contactless payments, e-commerce, international acceptance, supported form factors, and supported usage types.

Look these up when you need to know what a card issued from a given BIN or range can do.

GET /products/{card_product_id}/bins/{bin_id}
GET /products/{card_product_id}/bins/{bin_id}/ranges
GET /products/{card_product_id}/bins/{bin_id}/ranges/{bin_range_id}

GET /products/{card_product_id}/bins/{bin_id} returns the BIN itself. number is the same value you see as bin on a card:

A BIN
{
"bin_id": "bin_01937000-0592-7190-87e7-05921907e7c5",
"version": 1,
"version_time": "2026-01-15T18:32:00Z",
"number": "424242",
"country": "US",
"scheme": {
"network": "visa",
"funding_type": "debit",
"product_type": "classic"
},
"active": true,
"status": "active"
}

GET /products/{card_product_id}/bins/{bin_id}/ranges lists every range configured for that BIN on the product; GET .../ranges/{bin_range_id} returns a single one. Both return the same shape:

A BIN range
{
"bin_range_id": "bin_range_01937b28-f048-77de-8ef4-f0487deef42d",
"version": 1,
"version_time": "2026-01-15T18:32:00Z",
"bin_id": "bin_01937000-0592-7190-87e7-05921907e7c5",
"active": true,
"status": "active",
"currency": "USD",
"capabilities": {
"contactless_payments": true,
"ecommerce_enabled": true,
"international": {
"card_present_enabled": true,
"card_not_present_enabled": true,
"cross_border_authorization_enabled": false
},
"supported_form_factors": ["virtual"],
"supported_usage_types": ["reloadable"]
}
}

supported_form_factors lists the card form factors a range can issue. Today this is virtual.

status is one of reserved, active, deactivated, or deprecated for both a BIN and a BIN range, alongside an independent active flag. Issue new cards only against a BIN and range that are active.

Cards

A card is issued from a product to a cardholder and draws funds from a Capital Account. You can also scope its spend with a Control Account, which holds no balance of its own (see Accounts). Cards are created with POST /cards/virtual, and every card needs a cardholder: pass either an existing cardholder_id or an inline cardholder object to create the cardholder and the card in one call. See Issuing a Card for the full request shape.

Card reads include the BIN, the last four digits, and the expiration_date, but never the full card number or CVV. The unmasked PAN is available only from the separate, highly sensitive POST /cards/{card_id}/reveal endpoint, which requires the card:reveal permission and returns card_id, pan, cvv, expiration_month, and expiration_year.

A virtual card
{
"card_id": "card_019375de-a2a0-7f31-884a-a2a0f3184abd",
"version": 1,
"version_time": "2026-01-15T18:32:00Z",
"issued_time": "2026-01-15T18:32:00Z",
"expiration_date": "2030-06-30",
"bin_id": "bin_01937000-0592-7190-87e7-05921907e7c5",
"bin_range_id": "bin_range_01937b28-f048-77de-8ef4-f0487deef42d",
"bin": "424242",
"last_four": "4242",
"card_product_id": "card_product_01937f5d-a015-7a55-818b-a015a5518b97",
"business_id": "business_01937b95-484e-75af-8c68-484e5afc68d3",
"business_entity_id": "business_entity_01937c9d-3a1e-72b0-8881-3a1e2b088159",
"program_id": "program_019377de-7f88-7f02-894f-7f88f0294fcb",
"capital_account_id": "account_019372e3-b8dc-7de2-80b6-b8dcde20b6c9",
"control_account_id": "account_019372e3-9f4a-7c1b-9a3d-9f4a7c1b9a3d",
"cardholder_id": "cardholder_01937e19-4ebb-75bd-8250-4ebb5bd25085",
"status": "active",
"active": true,
"terminated": false,
"currency": "USD",
"country": "US",
"form_factor": "virtual",
"usage_type": "reloadable",
"scheme_details": {
"network": "visa",
"funding_type": "debit",
"product_type": "classic"
},
"alias": "Marketing Team Card",
"spend_control_id": "spend_control_019379d9-a170-796b-867a-a17096b67a21"
}

Assign or replace a card’s spend control with PUT /cards/{card_id}/spend_control (body {"spend_control_id": "..."}) and remove it with DELETE /cards/{card_id}/spend_control, both on the Issuing API.

Usage types

A card’s usage_type comes from its card product and can’t be changed after issuance. The product’s usage type must be listed in the BIN range’s supported_usage_types. Penny enforces each usage type on every authorization, alongside the card’s spend controls.

TypeBehavior
single_useThe card approves one authorization. If that authorization expires or is cancelled before it settles, the card can be used again. The first settlement terminates the card, and the card is also closed at the card issuer automatically. A settlement that arrives without a prior authorization counts as the card’s use.
single_reloadThe card has a lifetime budget, set with load_amount when the card is created. Approved authorizations and settled spend count against it; authorizations that expire or are cancelled return their amount. An authorization larger than the remaining budget is declined. The budget can’t be raised, and the card stays open when it’s spent.
reloadableThe card can be reused without a usage limit, subject to its spend controls.

Cards with a single_use or single_reload usage type include a read-only usage_limits object:

usage_limits on a single_reload card
"usage_limits": {
"authorizations_maximum": null,
"authorizations_used": null,
"amount_limit": "250.00",
"amount_remaining": "180.00"
}

On a single_use card, authorizations_maximum is 1 and authorizations_used shows whether the use is taken; the amount fields are null. Amounts are in the card’s currency.

Lifecycle

A new card is active as soon as it’s issued, or deactivated if you create it with "active": false. From there it can move between active, suspended (temporary), and deactivated. Terminating a card (DELETE /cards/{card_id}) sets it to terminated, which is permanent: use it only when a card should never be used again, not for a temporary pause.

See Issuing a Card for a full walkthrough from cardholder to first transaction.