Last updated

Issuing cards

Create a virtual card and receive its full details in one call.

A card is created with a single POST /v1/cards request. Unlike processors that provision asynchronously, the Jeeves response is synchronous and complete: the 201 body carries the card's full number, holder, expiry, and CVV. This page covers the request shape, the sensitive-details contract, and the errors to handle.

Request shape

curl -X POST \
  'https://public-sandbox.tryjeeves.com/v1/cards' \
  -H "Authorization: Bearer $JEEVES_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Travel Card",
    "metadata": {
      "reservation_code": "abc123",
      "passenger_name": "John Doe"
    },
    "expectedChargeDateUTC": "2026-10-02",
    "restrictions": {
      "spendLimit": 1000,
      "activeDateRangeUTC": {
        "startDate": "2026-10-01 00:00:00",
        "endDate": "2026-10-15 23:59:59"
      },
      "maxTransactionCount": 1,
      "merchantCategory": {
        "mode": "allow",
        "categoryIds": ["Airfare", "Lodging & Accommodations"]
      }
    }
  }'
FieldRequiredNotes
nameYes1–60 chars, alphanumeric and spaces only (^[a-zA-Z0-9\s]+$).
restrictions.spendLimitYesMaximum total spend in the card's local currency. Must be greater than 0.
restrictions.activeDateRangeUTCNostartDate / endDate (UTC) bounding when the card can transact.
restrictions.maxTransactionCountNo1–10. Set to 1 for a single-use card.
restrictions.merchantCategoryNomode: allow (only these categories authorize) or mode: block (these categories decline), plus categoryIds. See Spend controls & MCC.
metadataNoUp to 10 key-value pairs; keys ≤ 50 chars, values ≤ 255 chars. Returned on the card and on its transactions — use it to tie cards to your own records.
expectedChargeDateUTCNoDate the card is expected to be charged. Must not be in the past. Requires the cards:multiple:write scope, enabled on request — contact Jeeves support.

Scope: cards:write.

The response carries the full card details

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "Travel Card",
  "metadata": { "reservation_code": "abc123", "passenger_name": "John Doe" },
  "expectedChargeDateUTC": "2026-10-02",
  "restrictions": { "spendLimit": 1000, "maxTransactionCount": 1 },
  "details": {
    "cardNumber": "1234567890123456",
    "cardHolder": "John Doe",
    "expiryDate": "12/27",
    "cvvCode": "123"
  },
  "createdAt": "2026-09-29 10:35:00",
  "updatedAt": "2026-09-29 10:35:00"
}

Handle details as cardholder data. Pass it directly to your payment or display flow. Never write the PAN or CVV to logs, analytics, queues, or persistent storage unless you are PCI-scoped for it. If you need the details again, fetch them on demand instead of caching.

Retrieving a card

Per the API schema, GET /v1/cards/{id} returns the same shape including details — every single-card retrieval is effectively a PAN reveal, so gate who in your system can call it. Scope: cards:read.

curl 'https://public-sandbox.tryjeeves.com/v1/cards/123e4567-e89b-12d3-a456-426614174000' \
  -H "Authorization: Bearer $JEEVES_ACCESS_TOKEN"

Listing cards

GET /v1/cards pages through every card owned by your credentials (page starting at 1, pageSize up to 500, default 20). The list rows omit details — fetch a single card when you need them.

curl 'https://public-sandbox.tryjeeves.com/v1/cards?page=1&pageSize=20' \
  -H "Authorization: Bearer $JEEVES_ACCESS_TOKEN"

Errors to handle

StatusWhen
400 Bad RequestValidation failed: name pattern, spendLimit ≤ 0, maxTransactionCount outside 1–10, past expectedChargeDateUTC, metadata over limits.
401 UnauthorizedMissing or expired bearer token, or the mTLS handshake failed.
403 ForbiddenToken lacks the cards:write scope (or cards:multiple:write for expectedChargeDateUTC).
404 Not FoundCard ID does not exist or belongs to another client (on retrieve).

Every response includes an x-trace-id header — include it when contacting support.

After issuance