Skip to main content
This guide shows how to call a third-party API with real card data through the Yuno PCI Proxy. If you have not read it yet, start with the PCI Proxy Overview.

Requirements

  • Your public-api-key and private-secret-key from the Yuno Dashboard.
  • A card stored with Yuno and its vaulted_token. See Enroll Payment Method.
  • The destination API you want to call, reachable over HTTPS on port 443, and registered on your destination allowlist.
Server-side onlyProxy requests detokenize card data and must only be made from your backend. Never expose your private-secret-key in client-side code.
1

Build the destination request

Write the request exactly as the destination API expects it — same body shape, same headers — but put vaulted token expressions where the card data belongs:
The card fields you can reference are number, expiration_month, expiration_year, and holder_name — they resolve to the stored card (PAN) data. If the card was enrolled with a security code, you can also reference security_code, within a bounded window — see below. If the card has a network token, you can also reference network_token_number (the DPAN), network_token_expiration_month, and network_token_expiration_year. And network_transaction_id resolves to the card’s NTID — the scheme’s reference for its original transaction, required by many processors for merchant-initiated transactions. All fields can be mixed in the same request — send your processor whatever it needs: PAN, DPAN + NTID, or a combination. Provider tokens are not resolved, and neither are cryptograms — a cryptogram is generated per transaction, so if your destination requires one, obtain it from Generate Network Token Cryptogram right before the forward and include the value directly in the body. Request it with include_network_token: false if your organization is not PCI-certified: the cryptogram-only response carries no PAN-equivalent data, and the network_token_number expression resolves the DPAN for you at forward time.Expressions work in the request body and in header values. Everything that is not an expression is forwarded untouched.
The security code expires — by default 3 hours after enrollmentsecurity_code is the one field with a lifetime. The security code is never stored: it is held briefly after your customer enters it, and Yuno stops serving it once that window closes. Reference it only for a charge that happens shortly after enrollment.When it is unavailable — expired, or never captured — the forward fails with EXPRESSION_RESOLUTION_FAILED naming security_code, and no partial substitution happens. Your PAN expressions are unaffected: an expired security code costs you that field only.If your destination requires the CVV outside that window, your customer must supply it and you include it directly in the body yourself; the proxy forwards it without storing it. Transmitting a raw security code keeps that request in your PCI scope.

Storing a security code

A card only has a security code to inject if one was supplied when it was enrolled. Send it as card.security_code on Enroll Payment Method:
Enroll without it and the card is still usable for every other expression — only security_code will be unavailable.

Checking how much of the window is left

Read card_data.security_code_expires_in from Retrieve Enrolled Payment Method:
The enrollment response does not include security_code_expires_in. Read it from the payment method endpoint above when you need to know where you stand before building a forward.
2

Send it through the proxy

Send the request to https://api.y.uno/v1/pci-proxy/forward with the destination in the yuno-proxy-destination-url header:
The HTTP method you use is the method the destination receives. Headers you set for the destination (like Authorization above) pass through; Yuno’s own credential headers and all yuno-* headers are stripped before forwarding.The yuno-account-id header is optional: include it when you need to scope the request to a specific account. Like all yuno-* headers it is removed before forwarding and never reaches the destination. It narrows which allowlisted destinations are permitted for the request; it does not affect token resolution — vaulted tokens are always scoped to your organization.Put the complete destination URL — including its path and any query string — in yuno-proxy-destination-url (for example https://api.example-processor.com/charges/ch_123/capture?expand=true). Do not add a path or query string to the /v1/pci-proxy/forward request itself; a query string on the proxy request is rejected, so that merchant data is never logged.
3

Read the response

The destination’s status code, headers, and body are returned to you unchanged, except that any card number the destination echoes back is redacted first (see Card data in responses below). Redirects are not followed: a 3xx from the destination is returned to you as-is, so you decide whether to follow it. The proxy adds diagnostic headers:
4

Handle errors

Errors produced by the proxy itself use the standard Yuno error format and never include the yuno-proxy-destination-status header:
A 401 is returned before your request reaches the proxy, so it does not carry the yuno-proxy-request-id header; every other response does.Any 4xx/5xx accompanied by yuno-proxy-destination-status is the destination’s own error, passed through for you to handle as if you had called it directly.

Content types

The proxy is content-type agnostic. It forwards the body verbatim, without parsing or coercing it to JSON. Expression resolution is a text substitution over the raw body bytes, so a vaulted_token expression is replaced wherever it appears — JSON, XML, SOAP, or form key-value pairs. Place the expressions inside your payload and send the Content-Type your destination expects. JSON is shown above. The examples below cover the other common formats. XML
SOAP — an XML envelope plus the destination’s own SOAPAction header, forwarded unchanged:
Form key-value pairs (application/x-www-form-urlencoded):
Special characters in holder_nameBecause substitution is literal, a holder_name containing markup or delimiter characters can break the payload structure at the destination:
  • XML / SOAP: a name with &, <, or > (for example Doe & Sons) can break well-formedness. The number, expiration_month, and expiration_year fields are digits only, so they are unaffected — the risk is limited to holder_name.
  • Form key-value pairs: a name with &, =, or spaces can break the key/value structure. Send holder_name URL-encoded, or use a JSON/XML payload if the holder name may contain special characters.

Card data in responses

If a destination echoes a card number back in its response, the proxy redacts it before returning the response to you — keeping only the last four digits — so raw card numbers never reach your systems. The number of redactions is reported in the yuno-proxy-response-redactions response header:
A non-zero yuno-proxy-response-redactions is a signal that your destination is returning card data you should not receive. Redaction is the default behavior. Yuno can optionally be configured — as a service-wide setting, not per account — to instead reject any response containing card data with 502 RESPONSE_BLOCKED.

Authenticating to the destination

A proxy request carries two independent sets of credentials:
  • Your Yuno credentials (public-api-key / private-secret-key) authenticate you to the proxy. They are consumed by Yuno and never forwarded.
  • The destination’s own credentials are whatever that third-party API expects. Put them on the request and they are forwarded untouched — Yuno only strips its own headers.
Send whatever authentication header your destination requires — it is not limited to Authorization. The header name is defined by the destination provider’s API, not by Yuno; take it from that provider’s own documentation. What Yuno forwards vs. removes: Common authentication header names by provider (examples — always check the destination’s docs):

Signed destinations (HMAC request signing)

Some destinations require every request to be signed (HMAC) over the request body. You cannot pre-compute that signature yourself: it would have to be calculated over the resolved body — the one containing the real card number — which only exists inside Yuno’s secure environment. Instead, send your signing credentials on the request itself and the proxy signs for you, after resolving your expressions: The destination’s other identifiers are plain destination headers you send yourself, forwarded verbatim as always. For dLocal (DLOCAL_HMAC):
Each yuno-proxy-auth value identifies a complete, fixed signing scheme — what is signed, how, and which headers the proxy produces — matching that destination’s official authentication specification. DLOCAL_HMAC implements dLocal’s request-signing scheme: The signature is computed over the exact body bytes the destination receives — after your {{vaulted_token…}} expressions are resolved — which is precisely why the proxy must compute it. What the destination receives:
Do not send X-Date or Authorization yourself on a signed destination — the proxy’s values replace them (a signature you computed over a body still containing {{vaulted_token…}} placeholders would be rejected by the destination anyway). All your other headers pass through untouched. An unknown yuno-proxy-auth value, a missing yuno-proxy-auth-secret-key, or a DLOCAL_HMAC request without the X-Login or X-Trans-Key headers is rejected with 400 INVALID_REQUEST before the destination is contacted. A 401 from the destination itself (wrong credentials) comes back as a destination response, with yuno-proxy-destination-status: 401.
Mutual TLS is not yet supportedDestinations that require mutual TLS (a client certificate) are not supported inline: the certificate is presented by Yuno during the TLS handshake, not sent in your request, so it must be configured with Yuno per destination rather than passed in the body or a header. mTLS is planned for a later release.

Timeouts

The proxy waits up to 30 seconds for the destination by default. Override it with the yuno-proxy-timeout header (seconds, maximum 120):

Testing in sandbox

Use https://api-sandbox.y.uno/v1/pci-proxy/forward with your sandbox credentials and sandbox vaulted_token values. Sandbox tokens resolve to test card numbers, so you can point the proxy at your destination’s own sandbox safely.
Verify your integrationCheck yuno-proxy-replacements in the response while integrating: it confirms the proxy found and replaced your expressions before forwarding.