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_ and binds it to session_. The OTP is valid for 10 minutes. No authentication required.
Request
Authentication: none.
Body
| Field | Type | Description |
|---|---|---|
session_ required | string, uuid | Session 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 required | string, email | The cardholder's email address. Stored on the session and echoed in the response. |
card_ required | string | Number of the card to activate; at minimum its last 4 digits. CARD_ when no card matches. |
pin required | string | Card 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
| Field | Type | Description |
|---|---|---|
email required | string | Echo 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_ when no card matches card_.
The body is the standard error object: see Errors.
500 Error
Unexpected server error. Body is { message: "Internal server error", code: "INTERNAL_.
The body is the standard error object: see Errors.
Last updated August 16, 2026