Skip to main content
When 3D Secure runs as part of Secure Fields or the mobile SDKs, the resulting authentication data is available as payload placeholders in a Vault Forward request. This lets you pass 3DS data alongside card details to downstream endpoints that require it. 3DS forwarding requires a checkout session — use x-vault-forward-checkout-session instead of x-vault-forward-payment-methods. See CVV & Secure Fields for how to set up the checkout session.

Placeholders

The following 3DS placeholders are available when 3DS authentication has run via a checkout session:
PlaceholderDescription
CARD_3DS_CAVV_1Cardholder Authentication Verification Value (CAVV) generated by the issuer.
CARD_3DS_ECI_1Electronic Commerce Indicator (ECI) — the security level of the transaction.
CARD_3DS_VERSION_13D Secure protocol version used (for example 2.1.0).
CARD_3DS_DIRECTORY_RESPONSE_1Status returned by the directory server (for example C for Challenge Required).
CARD_3DS_AUTHENTICATION_RESPONSE_1Final result of the authentication challenge (for example Y for Successful).
CARD_3DS_SERVER_TRANSACTION_ID_1UUID assigned to this transaction by the 3DS server.
CARD_3DS_DS_TRANSACTION_ID_1UUID assigned by the Directory Server (dsTransID).
CARD_3DS_SCHEME_1Card scheme used during 3DS (for example visa, mastercard).
All 3DS placeholders use _1 because you can only provide one checkout session per Vault Forward request.

Example

POST /vault-forward
host: api.acme.gr4vy.app
content-type: application/json
x-vault-forward-url: https://example.com/endpoint
x-vault-forward-http-method: POST
x-vault-forward-header-authorization: Bearer 123
x-vault-forward-checkout-session: b77fef6d-c360-4b42-8f70-d884f4a6852a

{
    "card": {
        "number": "{{ CARD_NUMBER_1 }}",
        "expiry": "{{ CARD_EXPIRATION_DATE_1 }}",
        "cvv": "{{ CARD_SECURITY_CODE_1 }}"
    },
    "authentication": {
        "cavv": "{{ CARD_3DS_CAVV_1 }}",
        "eci": "{{ CARD_3DS_ECI_1 }}",
        "version": "{{ CARD_3DS_VERSION_1 }}"
    }
}

Conditional logic

3DS values may not always be present — for example, when authentication was not required or the transaction was frictionless. Use template logic to handle missing values gracefully.

If/else

{
    "authentication_response": {% if CARD_3DS_AUTHENTICATION_RESPONSE_1 %}"{{ CARD_3DS_AUTHENTICATION_RESPONSE_1 }}"{% else %}null{% endif %}
}

Or

The or operator outputs the first non-empty value:
{
    "authentication_response": "{{ CARD_3DS_AUTHENTICATION_RESPONSE_1 or CARD_3DS_DIRECTORY_RESPONSE_1 }}",
    "scheme": "{{ CARD_3DS_SCHEME_1 or "unknown" }}"
}