Cards

Learn how to create, update, manage, and reissue cards. Both virtual cards and physical cards are supported.

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
}
createdAn ISO 8601 timestamp (yyyy-MM-ddThh:mm:ssZ) for when the card was created.
cvv (Enterprise)Three digit CVV printed on the back of the card.
fundingSee Funding Source Schema.
exp_month (Enterprise)Two digit (MM) expiry month.
exp_year (Enterprise)Four digit (yyyy) expiry year.
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.
pan (Enterprise)Sixteen 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).
spend_limit_durationANNUALLY, FOREVER, MONTHLY, TRANSACTION.
stateCLOSED, OPEN, PAUSED, PENDING_ACTIVATION, PENDING_FULFILLMENT.
tokenGlobally unique identifier for the card.
typeMERCHANT_LOCKED, PHYSICAL, SINGLE_USE, VIRTUAL.
auth_rule_tokensList of tokens identifying any Auth Rules that apply to the card. Any Auth Rules that apply either at the card, account, or program level will appear.

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": "SINGLE_USE",
     "memo": "New Card",
     "spend_limit": 1000,
     "spend_limit_duration": "TRANSACTION",
     "state": "OPEN"
}
'

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "SINGLE_USE",
  "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": [
     "6397a416-bac6-464c-9647-b006f3a5f91d"
  ],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
}
memo (optional)Customizable name to identify the card.
String. Permitted values: Any.
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: SINGLE_USE, MERCHANT_LOCKED, VIRTUAL, PHYSICAL.
funding_token (optional)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).
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined.
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).
String. Permitted values: OPEN, PAUSED.
card_program_token (optional)Identifies the card program under which to create the card. Different card programs may have their own configurations (e.g., digital wallet card art, BIN type). This must be configured with Lithic before use.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
exp_month (optional)Two-digit (MM) expiry month. If neither exp_month nor exp_year is provided, an expiration date will be generated.
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.
String. Permitted values: Valid four-digit year.
account_token (required for programs with multiple accounts only)Globally unique identifier for the account that the card will be associated with. Only applicable if individual accounts are created under your program. See Managing Your Program for more information.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
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)Specifies the configuration (e.g., physical card art) that the card should be manufactured with, and only applies to cards of type PHYSICAL. This must be configured with Lithic before use.
String. Permitted values: 1 or more characters.
shipping_address (object, required if type is PHYSICAL)Shipping information for the physical card. 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.
- STANDARD: USPS regular mail or similar international option, with no tracking
- STANDARD_WITH_TRACKING: USPS regular mail or similar international option, with tracking
- EXPEDITED: FedEx Standard Overnight or similar international option, with tracking
String. Permitted values: STANDARD, STANDARD_WITH_TRACKING, EXPEDITED.
auth_rule_token (optional)Globally unique identifier for the Auth Rule to be applied to all transactions under the card.
String. Permitted values: 36-digit version 4 UUID (including hyphens).

Shipping Address Schema

Only applies to cards of type PHYSICAL.

first_name (required)Cardholder's first name. This will be the first name printed on the physical card.
String. Permitted values: 1-26 characters.
last_name (required)Cardholder's surname (family name). This will be the last name printed on the physical card.
String. Permitted values: 1-26 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, USA.
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.

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",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "SINGLE_USE",
  "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": [
     "6397a416-bac6-464c-9647-b006f3a5f91d"
  ],
  "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)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.
String. Permitted values: Any.
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined.
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.

List Cards

API Reference: List 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. If card_token is passed in as a path parameter, the endpoint returns a single object representing the card specified. Otherwise, a list of objects is returned.

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",
  "last_four": "4142",
  "hostname": "",
  "memo": "New Card",
  "type": "SINGLE_USE",
  "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": [
     "6397a416-bac6-464c-9647-b006f3a5f91d"
  ],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
}
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).
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)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.
page_size (optional, query parameter)For pagination - specifies the number of entries to be included on each page in the response. Default value is 50.
Integer. Permitted values: 1-1000.
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.

Reissue Card (Enterprise)

API Reference: Reissue card

Initiate print and shipment of a duplicate physical card (e.g., card is expiring, card is physically damaged, etc.) If the original card is still active, it will remain active until the new card has been received and 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": "SINGLE_USE",
  "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": [
     "6397a416-bac6-464c-9647-b006f3a5f91d"
  ],
  "pan": "4111111289144142",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
}
card_token (required, path parameter)Globally unique identifier for the card to be reissued.
String. Permitted values: 36-digit version 4 UUID (including hyphens).
product_id (optional)Specifies the configuration (e.g., physical card art) that the card should be manufactured with, and only applies to cards of type PHYSICAL. This must be configured with Lithic before use.
String. Permitted values: 1 or more characters.
shipping_address (object, required if type is PHYSICAL)Shipping information for the physical card. 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.
- STANDARD: USPS regular mail or similar international option, with no tracking
- STANDARD_WITH_TRACKING: USPS regular mail or similar international option, with tracking
- EXPEDITED: FedEx Standard Overnight or similar international option, with tracking
String. Permitted values: STANDARD, STANDARD_WITH_TRACKING, EXPEDITED.

Encrypted PIN Block (Enterprise)

Cardholder PINs can be configured for cards of type PHYSICAL and VIRTUAL. The create card and update card endpoints can set and update the cardholder PIN.

🚧

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

An Encrypted PIN block is a JSON blob, encrypted with the Lithic API public key, base64 digest.

api.lithic.com.pub.pem

{
  "nonce": Integer,
  "pin": 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(1e8, 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);
}

Enumerations

Card.type

MERCHANT_LOCKEDCard is locked to the first merchant that successfully authorizes the card
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
PHYSICAL (Enterprise)Manufactured 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)

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 7am Coordinated Universal Time (UTC), cards of type PHYSICAL in state PENDING_FULFILLMENT are sent to the card production warehouse and updated to state PENDING_ACTIVATION. Similar to PENDING_FULFILLMENT, cards in this state can be used for e-commerce transactions. 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 in a calendar 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. (Note month is calculated as this calendar date one month prior)
TRANSACTIONCard will authorize multiple transactions if each individual transaction is under the spend limit

Did this page help you?