Browse the docs

Create OTP for card activation

POST /v1/public/2fa/card/activate/otp

Step 2 of card activation: issues a one-time code for the card identified by card_number and binds it to session_id. The OTP is valid for 10 minutes. No authentication required.

Request

Authentication: none.

Body

FieldTypeDescription
session_id requiredstring, uuidSession id (UUID) obtained from GET /v1/public/2fa/session/id. The OTP is bound to it; send the same value to POST /v1/public/2fa/card/activate.
email requiredstring, emailThe cardholder's email address. Stored on the session and echoed in the response.
card_number requiredstringNumber of the card to activate; at minimum its last 4 digits. CARD_NOT_FOUND when no card matches.
pin requiredstringCard PIN: a string of exactly 4 digits.

Example request

cURL

curl --request POST \
     --url 'https://api.themooncard.com/v1/public/2fa/card/activate/otp' \
     --header 'content-type: application/json' \
     --data '{
       "session_id": "0d7f3a2b-5c1e-4f6a-9b8d-2e4c6a8b0d1f",
       "email": "jane@example.com",
       "card_number": "4111111111111111",
       "pin": "1234"
     }'

Responses

200 Success
FieldTypeDescription
email requiredstringEcho of the email the OTP was issued for.

JSON

{
  "email": "jane@example.com"
}
400 Error

Validation failed (errors[]), or { message: "Card not found", code: "CARD_NOT_FOUND" } when no card matches card_number.

The body is the standard error object: see Errors.

500 Error

Unexpected server error. Body is { message: "Internal server error", code: "INTERNAL_SERVER_ERROR" }.

The body is the standard error object: see Errors.

Last updated August 16, 2026