---
title: "Set a card PIN"
method: POST
path: "/cards/{id}/set-pin"
tags: ["Cards"]
---

# Set a card PIN

`POST /cards/{id}/set-pin`

## Request

- Base URL: `https://api.lightspark.com/grid/2025-10-13`
- URL: `https://api.lightspark.com/grid/2025-10-13/cards/{id}/set-pin`
- Auth: HTTP basic

Set or replace the card's online PIN using a block encrypted in your client with the published PIN encryption public key. Grid cannot decrypt the block and never stores or logs PIN material.

Use this when you operate your own PIN-entry UI. For a hosted PIN-entry iframe, use `GET /cards/{id}/pin-entry-url` — the two are alternatives, and a card may use either at any time.

Setting a PIN clears a `BLOCKED` PIN, so a cardholder locked out by incorrect attempts can recover by choosing a new PIN without a separate unblock. Read `GET /cards/{id}` for the resulting status. Grid supports online PINs only; offline PIN cards are not supported.

Every call is audit-logged with the requesting actor.

## Request body

- CardPinSetRequest
  - `encryptedPinBlock` string, required: The cardholder's PIN, encrypted in your client before calling Grid. Use the [PIN encryption public key](https://docs.lightspark.com/keys/pin-encryption-public-key.pem.txt) for both sandbox and production. Grid cannot decrypt the block and never stores or logs PIN material. Build it in the client, immediately after PIN entry, so the PIN never reaches your servers either: serialize `{"nonce": <random integer>, "pin": "<4-digit PIN>"}` as JSON, encode it as UTF-8, encrypt it using the public key above, and base64-encode the ciphertext. Generate a fresh cryptographically random integer `nonce` for each request to prevent replay. Preserve the PIN as a string, including leading zeros. Send the resulting base64 string as `encryptedPinBlock`. Never send the plaintext PIN or the unencrypted JSON to Grid. Keep ciphertext out of logs, storage, and analytics too. A rejected block returns `400 INVALID_INPUT`. Check the payload, encoding, and public key, then create a new block with a fresh nonce. See [Card PINs](https://docs.lightspark.com/cards/card-management/pins) for the complete PIN-entry flows.

## Response `204`

PIN change accepted.

## Other responses

- `400`: Bad request. Returned with `INVALID_INPUT` when `encryptedPinBlock` is absent, is not valid base64, or the encrypted block is rejected.
- `401`: Unauthorized
- `403`: Forbidden. The session has no attributable actor to audit the change against (for example, an impersonated dashboard session).
- `404`: Card not found
- `409`: Conflict. Returned with `CONFLICT` for a closed card or a card that does not support PIN management.
- `500`: Internal service error
- `501`: Not implemented in this environment. Cards are not enabled for every Grid deployment; environments without card support return `501 NOT_IMPLEMENTED`.

## Changes

> 115 revisions in range; 2 not diffed.

- **2026-10-28** `d996ddfb9d2b`: 5 info
  - added the optional property `details/missingFields` to the response with the `400` status
  - added the optional property `details/permission` to the response with the `403` status
  - added the optional property `details/policyDenialReason` to the response with the `403` status
  - added the optional property `details/refusalReason` to the response with the `400` status
  - …1 more
- **2026-10-28** `5abf2bb56bcb`: 1 warning
  - added the new `CORRIDOR_UNDER_MAINTENANCE` enum value to the `code` response property for the response status `403`
- **2026-10-26** `f11f1e76bdd7`: 1 warning
  - added the new `PURCHASE_CARD_LIMIT_REACHED` enum value to the `code` response property for the response status `409`
- **2026-10-26** `0a6dad5815c7`: 1 warning
  - added the new `INVOICE_ALREADY_USED` enum value to the `code` response property for the response status `409`
- **2026-10-24** `715332dcb111`: 1 warning
  - added the new `EXACT_AMOUNT_UNAVAILABLE` enum value to the `code` response property for the response status `400`

[Operation history](https://skmtc.dev/lightsparkdev/apis/grid-api/changes/cards/:id/set-pin/post.md)

---

[API](https://skmtc.dev/lightsparkdev/apis/grid-api.md) - [All operations](https://skmtc.dev/lightsparkdev/apis/grid-api/llms.txt) - [OpenAPI document](https://skmtc.dev/lightsparkdev/apis/grid-api/revisions/7a1db46ec552?raw)
