Cards

Learn how to create, update cards.

Card Schema

{
  "created": String,
  "cvv": String,
  "funding": Object,
  "exp_month": String,
  "exp_year": String,
  "hostname": String,
  "last_four": String,
  "memo": String,
  "pan": String,
  "spend_limit": Integer,
  "spend_limit_duration": String,
  "state": String,
  "token": String,
  "type": String,
  "auth_rule_tokens": List,
  "digital_card_art_token": String,
  "account_token": String,
  "card_program_token": String,
  "product_id": String,
  "pin_status": String,
  "pending_commands":[]
}
createdAn RFC 3339 timestamp for when the card was created.
cvvThree digit CVV/CVC printed on the back of the card. Only available in Production for customers who have verified PCI compliance. Available in Sandbox for all users.
funding(Deprecated) See Funding Source Schema.
exp_monthTwo digit (MM) expiry month. Expiration cannot be more than six years from present month.
exp_yearFour digit (yyyy) expiry year. Expiration cannot be more than six years from present month.
hostnameHostname of card’s locked merchant (will be empty if not applicable).
last_fourLast four digits of the card number.
memoCustomizable name to identify the card. We recommend against using this field to store JSON data as it can cause unexpected behavior.
panSixteen digit card number. Only available in Production for customers who have verified PCI compliance. Available in Sandbox for all users.
spend_limitAmount (in cents) to limit approved authorizations. Purchase requests above the spend limit will be declined (refunds and credits will be approved).

See Spend Limits for more details.
spend_limit_durationANNUALLY, FOREVER, MONTHLY, TRANSACTION.

Note that to support recurring monthly payments, which can occur on different day every month, the time window we consider for MONTHLY velocity starts 6 days after the current calendar date one month prior.
stateCLOSED, OPEN, PAUSED, PENDING_ACTIVATION, PENDING_FULFILLMENT.
tokenGlobally unique identifier for the card.
typeVIRTUAL, PHYSICAL, SINGLE_USE,MERCHANT_LOCKED (deprecated), .
auth_rule_tokens(Deprecated) - Auth_rule_tokens will always be sent as an empty array (changelog). See List Auth Rules.
digital_card_art_tokenSpecifies the digital card art to be displayed in the user’s digital wallet after tokenization. This artwork must be approved by Mastercard and configured by Lithic to use. See Flexible Card Art Guide.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
account_tokenGlobally unique identifier for the account to which the card belongs.
card_program_tokenGlobally unique identifier for the card program on which the card exists.
product_idOnly applicable to cards of type PHYSICAL. This must be configured with Lithic before use. Specifies the configuration (i.e., physical card art) that the card should be manufactured with.
pin_statusIndicates if a card is blocked due to a PIN status issue (e.g. excessive incorrect attempts). Currently supported values are: OK, BLOCKED, NOT_SET
pending_commandsApplicable only to cards issued in markets supporting offline PINs. Indicates if there are offline PIN changes pending card interaction with an offline PIN terminal.

📘

Due to PCI compliance requirements, the panand cvv fields are only available for customers who have verified PCI compliance.

All customers will see these fields in Sandbox.

Create Card

API Reference: Create card

Create either a virtual or physical card.

🚧

Before physical cards can be issued, there are a few onboarding steps with external party dependencies that must be completed. Please Contact Us or your Customer Success rep for more information. Steps required include:

  1. Establish and validate new BINs with the network and card manufacturer; this ensures that BINs are set up correctly and are ready for use, that transactional data will be sent securely, and that physical cards can be issued by the manufacturer
  2. Set up requirements for card manufacturing (e.g., card art)
  3. Test and confirm card configurations (e.g., spend testing, shipping) for final approval
POST https://api.lithic.com/v1/cards

Sample Request

curl https://api.lithic.com/v1/cards \
  -X POST \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
     "type": "VIRTUAL",
     "memo": "New Card",
     "spend_limit": 1000,
     "spend_limit_duration": "TRANSACTION",
     "state": "OPEN",
     "digital_card_art_token": "cc907ab5-541e-44ce-8fed-340ca1f00da0"
     }
}
'

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "account_token": "f3f4918c-dee9-464d-a819-4aa42901d624",
  "card_program_token": "5e9483eb-8103-4e16-9794-2106111b2eca",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "VIRTUAL",
  "spend_limit": 1000,
  "spend_limit_duration": "TRANSACTION",
  "state": "OPEN",
  "funding": {
    "created": "2020-07-08 17:57:36",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING",
    "state": "ENABLED",
    "nickname": "",
    "account_name": "New Account",
    "last_four": "5263",
  },
  "auth_rule_tokens": [],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
  "pin_status": "OK",
  "pending_commands": []
}
type (required)Type of card to be created. Cards of PHYSICAL type require additional privileges. All cards of PHYSICAL type have digital wallet functionality and will authorize at any merchant .
String. Permitted values: VIRTUAL, PHYSICAL, SINGLE_USE, MERCHANT_LOCKED (deprecated).
account_token (required for programs enrolling users)Globally unique identifier for the account that the card will be associated with. Required for programs enrolling users using the /account_holders endpoint. See Managing Your Program for more information.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
memo (optional)Customizable name to identify the card. We recommend against using this field to store JSON data as it can cause unexpected behavior.
String. Permitted values: Any.
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined. See Spend Limits for more details
Integer. Permitted values: 0 or greater.
spend_limit_duration (optional)Duration for which spend limit applies.
String. Permitted values: TRANSACTION, MONTHLY, ANNUALLY, FOREVER.
state (optional)Indicates whether or not the card is in an active state (i.e., transactions can be accepted). All physical cards will automatically be created in the PENDING_FULFILLMENT state.
String. Permitted values for virtual cards: OPEN, PAUSED.
exp_month (optional)Two-digit (MM) expiry month. If neither exp_month nor exp_year is provided, an expiration date will be generated. Expiration cannot be more than six years from present month.
String. Permitted values: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12.
exp_year (optional)Four-digit (yyyy) expiry year. If neither exp_month nor exp_year is provided, an expiration date will be generated. Expiration cannot be more than six years from present month.
String. Permitted values: Valid four-digit year.
digital_card_art_token
(optional)
Specifies the digital card art to be displayed in the user’s digital wallet after tokenization. This artwork must be approved by Mastercard and configured by Lithic to use. See Flexible Card Art Guide.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
card_program_token (optional)For card programs with more than one BIN range. This must be configured with Lithic before use. Identifies the card program/BIN range under which to create the card. If omitted, the program's defaultcard_program_token will be used. Different card programs may have their own configurations (e.g., digital wallet card art, BIN type).
String. Permitted values: 36-digit version 4 UUID (including hyphens). In Sandbox, use 00000000-0000-0000-1000-000000000000 and 00000000-0000-0000-2000-000000000000 to test creating cards on specific card programs.
pin (optional)Encrypted PIN block (in base64). Applies to cards of type PHYSICAL and VIRTUAL. See Encrypted PIN Block.
String. Permitted values: Valid JSON blob.
product_id (optional)Required for cards of type PHYSICAL and only applies to cards of type PHYSICAL. This must be configured with Lithic before use. Specifies the configuration (i.e., physical card art) that the card should be manufactured with.
String. Permitted values: 1 or more characters.
carrier (optional)Information to be printed on the physical card carrier (i.e., the piece of paper the physical card comes attached to). See Carrier Schema.
Object. Permitted values: Valid carrier object.
shipping_address (object, required if type is PHYSICAL)Shipping information for the physical card. Only applies to cards of type PHYSICAL. See Shipping Address Schema.
Object. Permitted values: Valid shipping_address object.
shipping_method (optional)Shipping method for the card. Only applies to cards of type PHYSICAL. Default is STANDARD if not provided. Use of options besides STANDARD require additional permissions and may not be offered by every card manufacturer.

- STANDARD: USPS regular mail or similar international option, no tracking
- STANDARD_WITH_TRACKING: USPS regular mail or similar international option, with tracking
- PRIORITY: USPS Priority, 1-3 day shipping, with tracking
- EXPRESS: FedEx Express, 3-day shipping, with tracking
- 2_DAY: FedEx 2-day shipping, with tracking
-EXPEDITED: FedEx Standard Overnight or similar international option, with tracking
String. Permitted values: STANDARD, STANDARD_WITH_TRACKING, PRIORITY, EXPRESS, 2_DAY,EXPEDITED.
replacement_for (optional)Only applicable to cards of type PHYSICAL. Globally unique identifier for the card that this physical card will replace. See Replace Physical Card for more details.

Shipping Address Schema

Only applies to cards of type PHYSICAL. Physical cards are not created immediately; all physical card creation requests are batched each morning to be manufactured.

first_name (required)Cardholder's first name. This will be the first name printed on the physical card.
String. Permitted values: 1-24 characters. The combined length of first_name and last_name may not exceed 25 characters.
last_name (required)Cardholder's surname (family name). This will be the last name printed on the physical card.
String. Permitted values: 1-24 characters. The combined length of first_name and last_name may not exceed 25 characters.
line2_text (optional)Text to be printed on line two of the physical card. Use of this field requires additional permissions.
String. Permitted values. 1-26 characters.
address1 (required)Valid USPS routable address.
String. Permitted values: 1-40 characters.
address2 (optional)Unit number (if applicable).
String. Permitted values: 1-40 characters.
city (required)City name.
String. Permitted values: 1-30 characters.
state (required if country is USA or CAN)State name.
String. Permitted values: Uppercase ISO 3166-2 two-character abbreviation for USA and Canada-based addresses. Optional with a limit of 24 characters for other countries.
postal_code (required)Postal code.
String. Permitted values: 1-12 characters. For US addresses, either five-digit zipcode or nine-digit "ZIP+4".
country (required)Country name. Use of non-USA addresses require additional permissions.
String. Permitted values: Uppercase ISO 3166-1 alpha-3 three-character abbreviation. For example, US.
email (required if shipping_method is EXPEDITED)Email address to be contacted for expedited shipping process purposes.
String. Permitted values: Valid email address. For example, [email protected].
phone_number (required if shipping_method is EXPEDITED)Cardholder's phone number to be contacted for expedited shipping process purposes. String. Permitted values: Phone number in E.164 format. For example, +12124007676 for US phone numbers.

Upon creation of a physical card, the card details can immediately be provided to the cardholder to be used virtually until they receive the physical card. The reverse (creating a virtual card, then later provisioning a physical version with the same card details) is not possible.

Carrier Schema

Only applies to cards of type PHYSICAL. Contains information to be printed on each physical card carrier (i.e., the piece of paper the physical card comes attached to).

qr_code_url (optional)URL to be transformed into a QR code on the physical card carrier. Can be dynamic per card; Lithic validates this URL against a base URL(s) submitted to Lithic during implementation.

List Cards

API Reference: List cards

GET https://api.lithic.com/v1/cards

Get details for all cards or a specified card. This endpoint can only be used for cards that are managed by the program associated with the calling API key.

Sample Request

curl https://api.lithic.com/v1/cards \
  -H "Authorization: YOUR_API_KEY"

Sample Response


{
  "data": [
    {
      "created": "2021-06-28T22:53:15Z",
      "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
      "account_token": "f3f4918c-dee9-464d-a819-4aa42901d624",
      "card_program_token": "5e9483eb-8103-4e16-9794-2106111b2eca",
      "last_four": "4142",
      "hostname": "",
      "memo": "New Card",
      "type": "VIRTUAL",
      "spend_limit": 2000,
      "spend_limit_duration": "FOREVER",
      "state": "OPEN",
      "funding": {
        "created": "2020-07-08 17:57:36",
        "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
        "type": "DEPOSITORY_CHECKING",
        "state": "ENABLED",
        "nickname": "",
        "account_name": "New Account",
        "last_four": "5263",
      },
      "auth_rule_tokens": [],
      "pan": "4111111289144142",
      "cvv": "776",
      "exp_month": "06",
      "exp_year": "2027",
      "pin_status": "OK",
      "pending_commands": []
    }
  ]
  "page": 1,
  "total_entries": 1,
  "total_pages": 1
}
card_token (optional, path parameter)Globally unique identifier for the card. If using this parameter, do not include other parameters in the request.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
account_token (optional, query parameter)Globally unique identifier for an account. This endpoint will return cards associated with this account if included in the request.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
state (optional, query parameter)Cards with the specified state will be included. Can either be a single value or multiple values separated by commas (e.g. OPEN,CLOSED).
String. Permitted values: OPEN, CLOSED, PAUSED, PENDING_FULFILLMENT, PENDING_ACTIVATION
begin (optional, query parameter)Cards created on or after the specified date will be included.
String. Permitted values: Date string in the form YYYY-MM-DD.
end (optional, query parameter)Cards created before the specified date will be included (i.e., cards created on the specified date will not be included).
String. Permitted values: Date string in the form YYYY-MM-DD.
starting_after (optional)For pagination - specifies the first object in a list to be returned. Requests can only use either starting_after or ending_before.
For example, you have a list of 100 Disputes objects where the first entry is UUID abcd and last entry is UUID wxyz. A request of starting_after = abcd and page_size = 100 will return 99 results (abcd is excluded from the response)
String. Permitted values: 36-digit version 4 UUID (including hyphens)
ending_before (optional, query parameter)For pagination - specifies the last object in a list to be returned. Requests can only use either starting_after or ending_before.
For example, you have a list of 100 Disputes objects where the first entry is UUID abcd and last entry is UUID wxyz. A request of ending_before = wxyz and page_size = 100 will return the full list of 100.
String. Permitted values: 36-digit version 4 UUID (including hyphens)
page (optional, query parameter)For pagination - specifies the desired page to be included in the response. For example, if there are 3 total entries, and page_size is 2 (i.e., 2 entries per page), then entering the value 2 for page would return the second page and only the third entry. The default is one.
Integer. Permitted values: 1 or greater.

Update Card

API Reference: Update card

Update the specified properties of the card. Unsupplied properties will remain unchanged.

PATCH https://api.lithic.com/v1/cards/{card_token}

Sample Request

curl https://api.lithic.com/v1/cards/7ef7d65c-9023-4da3-b113-3b8583fd7951 \
  -X PATCH \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
     "memo": "New Card",
     "spend_limit": 2000,
     "spend_limit_duration": "FOREVER"
}
'

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "account_token": "f3f4918c-dee9-464d-a819-4aa42901d624",
  "card_program_token": "5e9483eb-8103-4e16-9794-2106111b2eca",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "VIRTUAL",
  "spend_limit": 2000,
  "spend_limit_duration": "FOREVER",
  "state": "OPEN",
  "funding": {
    "created": "2020-07-08 17:57:36",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING",
    "state": "ENABLED",
    "nickname": "",
    "account_name": "New Account",
    "last_four": "5263",
  },
  "auth_rule_tokens": [],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
}
card_token (required, path parameter)Globally unique identifier for the card to be updated.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
state (optional)Indicates whether or not the card is in an active state (i.e., transactions can be accepted). Note that setting a card to a CLOSED state is a final action that cannot be undone.
String. Permitted values: OPEN, PAUSED, CLOSED.
funding_token (optional)(Deprecated) Globally unique identifier for the funding source to be used when transactions are made with this card.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
memo (optional)Customizable name to identify the card. We recommend against using this field to store JSON data as it can cause unexpected behavior.
String. Permitted values: Any.
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined. See Spend Limits for more details.
Integer. Permitted values: 0 or greater.
spend_limit_duration (optional)Duration for which spend limit applies.
String. Permitted values: TRANSACTION, MONTHLY, ANNUALLY, FOREVER.
pin (optional)Encrypted PIN block (in base64). Applies to cards of type PHYSICAL and VIRTUAL. See Encrypted PIN Block.
String. Permitted values: Valid JSON blob.

Get Specific Card

API Reference: Get card

GET https://api.lithic.com/v1/cards/{card_token}

Sample Request

curl https://api.lithic.com/v1/cards/7ef7d65c-9023-4da3-b113-3b8583fd7951 \
  -H "Authorization: YOUR_API_KEY"

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "account_token": "f3f4918c-dee9-464d-a819-4aa42901d624",
  "card_program_token": "5e9483eb-8103-4e16-9794-2106111b2eca",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "VIRTUAL",
  "spend_limit": 2000,
  "spend_limit_duration": "FOREVER",
  "state": "OPEN",
  "funding": {
    "created": "2020-07-08 17:57:36",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING",
    "state": "ENABLED",
    "nickname": "",
    "account_name": "New Account",
    "last_four": "5263",
  },
  "auth_rule_tokens": [],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
  "pin_status": "OK",
  "pending_commands": []
}
card_token (required, path parameter)Globally unique identifier for the card to be updated.
String. Permitted values: 36-digit version 4 UUID (including hyphens).

Renew Physical Card

As physical cards approach expiry, customers can renew physical cards, generating a physical card with the same card token and PAN, but updated expiry and CVC2 code. API Reference: Renew Physical Card

This flow is best suited for replacing a card approaching expiry. To set up a card renewal flow:

  1. Make a POST request to /cards/{card_token_UUID}/renew.
  2. This POST request will trigger a physical card shipment. As part of this POST request, you must specify an address for the card to be shipped.
  3. The card's state will change to PENDING_FULFILLMENT. Once the card has been created by the card manufacturer, the state will change again to PENDING_ACTIVATION. Once the card is delivered to the cardholder, you should activate it by changing state to OPEN.
  4. The new physical card will only start working for card-present transactions once activated (the state is changed from PENDING_ACTIVATION back to OPEN)
  5. The original physical card will keep working for card-present transactions until the new card is activated. For card-not-present transactions, the original card details (expiry, CVC2) will also keep working until the new card is activated.
  6. Lithic will pass along the updated card details to Mastercard's Automatic Billing Updater. Participating merchants will be able to update the card-on-file information.
POST https://api.lithic.com/v1/cards/{card_token}/renew

Sample Request

curl https://api.lithic.com/v1/cards/{card_token}/renew \
  -X POST \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
     "memo": "example card",
     "type": "PHYSICAL",
     "card_program_token": "1234abcd-ef5g-67h8-ijkl-m90n1a54f3d6",
     "product_id": "1",
     "shipping_address":{
        "first_name": "John",
        "last_name": "Appleseed",
        "address1": "1600 Pennsylvania Avenue NW",
        "city": "Washington",
        "state": "DC",
        "postal_code": "20500",
        "country": "USA"
}
'

Replace Physical Card

Replace a card with a new physical card with a different PAN (e.g. card was stolen). API Reference: Replace Physical Card.

This flow closes the original card and creates a new card with a new PAN, expiry, CVC2, and card token. This is best suited for replacing a lost or stolen card whose number is no longer secure. To set up a card replacement flow:

  1. Make a POST request to the /cards endpoint. In your request, specify the UUID of the card you want to replace in the replacement_for field.
  2. This POST request will trigger a physical card shipment. As part of this POST request, you must specify an address for the card to be shipped.
  3. Please note: this POST request will immediately change the predecessor physical card's state to CLOSED and that physical card will no longer be able to transact.
  4. The new card's state will change to PENDING_FULFILLMENT. Once the card has been created by the card manufacturer, the state will change again to PENDING_ACTIVATION. Once the card is delivered to the cardholder, you should activate it by changing state to OPEN.
  5. The replacement card will be created with the replacement_for field populated with the predecessor card's token for future reference.
  6. Lithic will pass along the updated card details to Mastercard's Automatic Billing Updater. Participating merchants will be able to update the card-on-file information.
POST https://api.lithic.com/v1/cards

Sample Request

curl https://api.lithic.com/v1/cards \
  -X POST \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
     "replacement_for": "d3ca4a3b-5c2d-4e1a-a94b-683adde7269c",
     "memo": "example card",
     "type": "PHYSICAL",
     "card_program_token": "1234abcd-ef5g-67h8-ijkl-m90n1a54f3d6",
     "product_id": "1",
     "shipping_address":{
        "first_name": "John",
        "last_name": "Appleseed",
        "address1": "1600 Pennsylvania Avenue NW",
        "city": "Washington",
        "state": "DC",
        "postal_code": "20500",
        "country": "USA"
}
'

Reissue Physical Card

Initiate print and shipment of a replacement physical card (e.g. card is physically damaged). API Reference: Reissue card.

📘

Note: We recommend customers use the Renew Physical Card or Replace Physical Card endpoints if possible. Please reference the table below to understand the differences

ReissueRenewReplace
Card tokensamesamenew
PANsamesamenew
Expirysamenewnew
CVC2samenewnew
New card can transactonce activatedonce activatedonce activated
Old card can transactuntil new card is activateduntil new card is activatedold card is closed immediately

When you reissue a physical card, the following will happen:

  1. The card state will change from OPEN to PENDING_FULFILLMENT. Once the card has been created by the card manufacturer, the state will change again to PENDING_ACTIVATION. Once the card is delivered to the cardholder, you should activate it by changing state to OPEN.
  2. The PAN, expiry, and CVC2 will remain the same (with the exception of cards created before 5/2023 - CVC2 will change in those cases). These credentials can be used for card-not-present transactions at any time.
  3. The new physical card will only start working for card-present transactions once activated (the state is changed from PENDING_ACTIVATION back to OPEN)
  4. The original physical card will keep working for card-present transactions until the new card is activated.
POST https://api.lithic.com/v1/cards/{card_token}/reissue

Sample Request

curl https://api.lithic.com/v1/card/7ef7d65c-9023-4da3-b113-3b8583fd7951/reissue \
  -X POST \
  -H "Authorization: YOUR_API_KEY"

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "VIRTUAL",
  "spend_limit": 2000,
  "spend_limit_duration": "FOREVER",
  "state": "OPEN",
  "funding": {
    "created": "2020-07-08 17:57:36",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING",
    "state": "ENABLED",
    "nickname": "",
    "account_name": "New Account",
    "last_four": "5263",
  },
  "auth_rule_tokens": [],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
  "pin_status": "OK",
  "pending_commands": []
}

Encrypted PIN Block

Cardholder PINs can be configured for cards of type PHYSICAL and VIRTUAL. You can provide cardholder PIN when creating cards using the create card endpoint. The update card endpoint can be used to set or update it later.

🚧

Due to their sensitive nature, PINs must be encrypted on the frontend immediately after user input.

Sample Request:

curl https://api.lithic.com/v1/cards/7ef7d65c-9023-4da3-b113-3b8583fd7951 \
  -X PATCH \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '
{
  "pin": "ENCRYPTED_PIN_BLOCK_STRING"
}

Sample Response:

{
    "created": "2022-11-08T21:56:22Z",
    "token": "4d4c2c5c-6bg0-5bbg-cg7d-z1bfydu38q2i",
    "last_four": "2879",
    "hostname": "",
    "memo": "debit",
    "type": "PHYSICAL",
    "spend_limit": 0,
    "spend_limit_duration": "TRANSACTION",
    "state": "OPEN",
    "funding": null
}

An Encrypted PIN block is a JSON blob, encrypted with the Lithic API public key, base64 digest. The Lithic API public key is: api.lithic.com.pub.pem

{
  "nonce": Integer,
  "pin": "ENCRYPTED_PIN_BLOCK_STRING"
}
nonceA cryptographic nonce to create additional entropy and prevent replay attacks. This should be unique per request. Integer should be at least 8 digits in length
pinCardholder PIN (between 4 and 12 numeric digits in length). String datatype to ensure leading zeros are not truncated

Examples

import base64
import json
import random

# pip install pycryptodome
from Crypto.Cipher    import PKCS1_OAEP
from Crypto.PublicKey import RSA

pin_block =  {
    "nonce": random.randint(int(1e8), int(1e12)),
    "pin": "1234"
}

with open("path/to/api.lithic.com.pub.pem") as f:
    cipher = PKCS1_OAEP.new(RSA.importKey(f.read()))

ciphertext = cipher.encrypt(json.dumps(pin_block).encode('utf-8'))

# Use this for the "pin" field value when creating or updating cards
encrypted_pin_block = base64.b64encode(ciphertext)
const fs = require("fs");

// npm install node-forge
const forge = require("node-forge");

const pem = fs.readFileSync("path/to/api.lithic.com.pub.pem", "utf8");
const publicKey = forge.pki.publicKeyFromPem(pem);

function randomInt(low, high) {
  // Generate random integer between low and high, inclusive
  return Math.floor(Math.random() * (high - low + 1) + low)
}

const pinBlock =  {
  "nonce": randomInt(1e8, 1e12),
  "pin": "1234"
}

const ciphertext = publicKey.encrypt(JSON.stringify(pinBlock), "RSA-OAEP", {
  md: forge.md.sha1.create(),
  mgf1: {
    md: forge.md.sha1.create()
  }
});

// Use this for the "pin" field value when creating or updating cards
const encryptedPinBlock = forge.util.encode64(ciphertext);
console.log(encryptedPinBlock);
package main

import (
	crand "crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	rand "math/rand"
	"os"
	"time"
)

type PinBlock struct {
	Nonce int    `json:"nonce"`
	Pin   string `json:"pin"`
}

func checkError(err error) {
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		os.Exit(1)
	}
}

func loadKey(fileName string) (*rsa.PublicKey, error) {
	rawPem, err := ioutil.ReadFile(fileName)
	checkError(err)

	pemBlock, _ := pem.Decode(rawPem)

	return x509.ParsePKCS1PublicKey(pemBlock.Bytes)
}

func encrypt(msg []byte, publicKey *rsa.PublicKey) (string, error) {
	encryptedBytes, err := rsa.EncryptOAEP(
		sha1.New(),
		crand.Reader,
		publicKey,
		msg,
		nil,
	)
	if err != nil {
		return "", err
	}
	encodedData := base64.StdEncoding.EncodeToString(encryptedBytes)
	return encodedData, nil
}

func generateNonce() int {
	rand.Seed(time.Now().UnixNano())
	min := int(1e8)
	max := int(1e12)
	return min + rand.Intn(max-min+1)
}

func main() {
	pemFile := "path/to/api.lithic.com.pub.pem"

	publicKey, err := loadKey(pemFile)
	
	pinBlock := &PinBlock{Nonce: generateNonce(), Pin: "1234"}
	pinBlockBytes, err := json.Marshal(pinBlock)
	checkError(err)
	fmt.Println(string(pinBlockBytes))

	// Use this for the "pin" field value when creating or updating cards
	encoded, err := encrypt(pinBlockBytes, publicKey)
	checkError(err)

	fmt.Println(encoded)
}
extern crate openssl;

use base64;
use openssl::rsa::{Padding, Rsa};
use rand::Rng;
use serde::Serialize;
use serde_json;

#[derive(Serialize)]
struct PinBlock {
    pin: String,
    nonce: u128,
}

// This is the main function
fn main() {
    let mut rng = rand::thread_rng();

    let base: u128 = 10;
    let low: u128 = base.pow(8);
    let high: u128 = base.pow(12);
    let nonce = rng.gen_range(low..high);

    let pin = "1234";

    let pin_block = PinBlock {
        pin: pin.to_string(),
        nonce: nonce,
    };

    let data = serde_json::to_string(&pin_block).unwrap();

    // Encrypt with public key
    let public_key_pem = include_bytes!("path/to/api.lithic.com.pub.pem");

    let rsa = Rsa::public_key_from_pem_pkcs1(public_key_pem).expect("Error prasing public key");
    let mut buf: Vec<u8> = vec![0; rsa.size() as usize];
    let _ = rsa
        .public_encrypt(data.as_bytes(), &mut buf, Padding::PKCS1_OAEP)
        .unwrap();
    
    let encrypted_pin_block = base64::encode(&buf);

    println!("Encrypted PIN block: {:?}", encrypted_pin_block);
}

Physical Card Shipped Webhook

When your physical cards are shipped, Lithic will send a webhook to your registered Events webhook URL(s) subscribing to events of type card.shipped with the below payload. Check with your customer success manager if your manufacturer supports this webhook.

{
  "event_type": "card.shipped",
  "card_token": "String",
  "shipping_method": "String",
  "tracking_number": "String"
}
event_typeEvent type. See Event Types for a full list of events.
card_tokenThe token of the card under which the tokenization is occurring.
shipping_methodShipping method for the card. Will beUSPS without tracking envelope (STANDARD) or FedEx overnight (EXPEDITED) depending on if STANDARD or EXPEDITED was passed in the shipping_method field upon card creation.
tracking_number (optional)Tracking number for the card shipment. If the card was shipped without a tracking number, this field will be empty.

Funding Source (deprecated)

{
  "created": String,
  "token": String,
  "type": String,
  "state": String,
  "nickname": String,
  "account_name": String,
  "last_four": String
}
createdAn RFC 3339 string representing when this funding source was added to the Lithic account. This may be null
tokenA globally unique identifier for this Funding Source
typeType of funding source, see Enumerations for list
stateState of funding source, see Enumerations for list
nicknameThe nickname given to the Funding Source or null if it has no nickname
account_nameAccount name identifying the funding source. This may be null
last_fourThe last 4 digits of the account (e.g. bank account, debit card) associated with this funding account. This may be null

Enumerations

Card.type

PHYSICALManufactured and sent to the cardholder. We offer white-label branding, credit, ATM, PIN debit, chip/EMV, NFC, and magstripe functionality. Contact [email protected] for more information
VIRTUALCard will authorize at any merchant and can be added to a digital wallet like Apple Pay or Google Pay (if the card program is digital wallet-enabled)
SINGLE_USECard will close shortly after the first transaction. After the first transaction, additional purchases will be declined, but the card will remain available to process refunds.

Note that merchants may still initiate force post charges (i.e., a clearing without a prior authorization) which Lithic is not able to decline. These may be subject to chargeback.
MERCHANT_LOCKED(Deprecated) Card is locked to the first merchant that successfully authorizes the card.

Card.state

CLOSEDCard will no longer approve authorizations. Closing a card cannot be undone
OPENCard will approve authorizations (if they match card and account parameters)
PAUSEDCard will decline authorizations but can be resumed at a later time
PENDING_ACTIVATIONEach day at a previously defined time cards of type PHYSICAL in state PENDING_FULFILLMENT are sent to the card production warehouse and updated to state PENDING_ACTIVATION. Cards in this state can accept authorizations for e-commerce purchases, but not for "Card Present" purchases where the physical card itself is present. API clients should update the card's state to OPEN only after the cardholder confirms receipt of the card.

In Sandbox, the same daily batch fulfillment occurs, but no cards are actually manufactured.
PENDING_FULFILLMENTThe initial state for cards of type PHYSICAL. The card is provisioned pending manufacturing and fulfillment. Cards in this state can accept authorizations for e-commerce purchases, but not for "Card Present" purchases where the physical card itself is present.

Card.spend_limit_duration

ANNUALLYCard will authorize transactions up to spend limit for the trailing year
FOREVERCard will authorize only up to spend limit for the entire lifetime of the card
MONTHLYCard will authorize transactions up to spend limit for the trailing month. To support recurring monthly payments, which can occur on different day every month, the time window we consider for monthly velocity starts 6 days after the current calendar date one month prior.
TRANSACTIONCard will authorize multiple transactions if each individual transaction is under the spend limit

FundingSource.state (deprecated)

ENABLEDThe funding source is available to use for card creation and transactions
PENDINGThe funding source is still being verified e.g. bank micro-deposits verification

FundingSource.type (deprecated)

DEPOSITORY_CHECKINGBank checking account
DEPOSITORY_SAVINGSBank savings account