Authentication and API keys
Choose the correct DEUNA public key, private key, and customer Bearer token for client-side, server-to-server, and signed-in user requests.
On this page
DEUNA credentials answer two different questions: which merchant application is calling, and, when applicable, which signed-in customer is using it. Start with where the request runs and whose authority it needs, then confirm the exact requirement in the endpoint catalog.
Decide which credential to use#
Ask these questions in order:
- Does the request run in a browser or mobile application? Use the public API key or application context documented for the SDK or endpoint. Never place the private key in that client.
- Does your backend perform a merchant operation? Use the private API key in
X-Api-Keyfor server-to-server calls such as creating, retrieving, capturing, refunding, or voiding an order. - Must DEUNA recognize the signed-in customer? Add the customer's short-lived access token as
Authorization: Bearer …only when the endpoint supports it. This is what gives the request customer-specific context for resources such as profile data, addresses, stored payment instruments, or customer-authorized wallet flows.
| Request scenario | Credential | Why |
|---|---|---|
| DEUNA SDK or widget running in a browser or mobile app | Public API key | Identifies the merchant application and environment without exposing merchant-backend authority. |
| Merchant backend calling a merchant endpoint | Private API key | Authorizes the merchant's trusted server-to-server operation. |
| Signed-in customer calling a customer endpoint | Public application context plus customer Bearer token, as documented by the endpoint | Identifies both the application and the customer whose resources the operation can access. |
| Merchant backend operation that also needs customer context | Private API key plus customer Bearer token, only when the endpoint explicitly supports both | Keeps merchant authorization and customer identity separate. |
| Guest customer flow | Public client context; no Bearer token unless the endpoint requires one | There is no signed-in DEUNA customer identity to attach. |
Choose the correct credential#
| Credential | Where it belongs | What it does |
|---|---|---|
| Public API key | Browser, mobile SDK, or another documented customer application | Initializes supported widgets, UI, and tokenization flows and identifies the merchant application and environment. It does not authorize private merchant operations. |
| Private API key | Trusted merchant backend only | Authorizes merchant server-to-server operations through X-Api-Key. |
| Customer access token | Signed-in customer flow | Adds customer identity through Authorization: Bearer … on endpoints that support it. It does not replace an API key required by the endpoint. |
| Admin session | DEUNA Admin | Gives an authorized operator role-based access; it is not an integration API credential. |
Public API key: client-side integration#
Use the public API key when DEUNA code runs in an untrusted client, such as a browser or mobile application. Typical uses include initializing a DEUNA widget or SDK and identifying the merchant and environment for supported client-side tokenization and payment experiences.
A public key is intentionally safe to include in client configuration, but it is not a secret substitute and it does not grant permission to perform captures, refunds, voids, or other merchant-backend operations. Keep the public key paired with the correct sandbox or production environment.
Private API key: server-to-server authorization#
Use the private API key when your trusted backend calls a merchant endpoint. Merchant operations that use API-key authorization expect the private key in X-Api-Key, never in Authorization: Bearer ….
curl --request GET \
--url https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN \
--header "X-Api-Key: YOUR_PRIVATE_API_KEY"const response = await fetch("https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN", {
method: "GET",
headers: {
"X-Api-Key": "YOUR_PRIVATE_API_KEY"
}
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"GET",
"https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN",
headers={
"X-Api-Key": "YOUR_PRIVATE_API_KEY"
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: YOUR_PRIVATE_API_KEY"
]
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN"))
.header("X-Api-Key", "YOUR_PRIVATE_API_KEY")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
)
func main() {
request, err := http.NewRequest("GET", "https://api.sandbox.deuna.io/merchants/orders/ORDER_TOKEN", nil)
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "YOUR_PRIVATE_API_KEY")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Customer Bearer token: signed-in user context#
Use a customer access token when the operation must act in the context of a signed-in DEUNA customer and the endpoint documents Bearer support. Send it in the Authorization header:
Authorization: Bearer USER_ACCESS_TOKENThe Bearer token answers which customer is acting. The API key answers which merchant application or backend is calling. Depending on the endpoint, a customer request can therefore require both an application API key and the customer's Bearer token.
Do not send a Bearer token for a guest flow merely because the header is available. Do not use a merchant private key as a Bearer token, and do not treat a customer token as authority for merchant-only operations. If your backend forwards customer context, forward it only to an endpoint that explicitly supports the combination.
Environments#
Sandbox and production are isolated. Each environment has its own base URL, API keys, merchant configuration, connections, data, and payment state.
Test the complete integration with sandbox credentials and provider test configuration.
Process live payments using the production merchant and production credentials.
Store and rotate keys#
- Store private keys in a secrets manager or protected runtime configuration.
- Scope access to the service and environment that need the key.
- Redact credentials from request logs and support attachments.
- Deploy a replacement key before revoking the old key so production traffic continues safely.
- Coordinate key issuance and rotation with your authorized Admin operator or DEUNA TAM.
Authentication failures#
An authorization failure normally returns 401 Unauthorized or 403 Forbidden. Before retrying, verify:
- The credential is present in the documented header.
- The key belongs to the requested environment and merchant.
- The endpoint supports the authorization method you sent.
- The key or customer token has not expired or been revoked.
- Any required merchant, store, or customer context is present.
Do not retry an authorization error indefinitely. Preserve the response request_id when available and include it when contacting support.
Rate limits#
DEUNA does not apply one public requests-per-second value to every integration. The API Gateway evaluates configured limits as a maximum number of requests within a time window. The effective limit can vary by merchant, environment, HTTP method, and endpoint.
| Gateway behavior | What it means for your integration |
|---|---|
| Scope | A limit can apply to one endpoint, be shared by endpoints that use the same backend service, or apply across the gateway. |
| Traffic bucket | Requests can be grouped by merchant ID, API key, customer Bearer token, source IP, or another configured request header. If an expected identity is absent, some rules fall back to the source IP. |
| Window | Each rule defines both the allowed request count and the duration of the counting window. Do not assume that all endpoints use the same window. |
| Route coverage | A route-specific limit is enforced only when a rule is configured for that method and endpoint. Platform-wide safeguards can still reject traffic during overload. |
When a request exceeds an applicable limit, the gateway returns 429 Too Many Requests with a Retry-After header. A route-level response has this shape:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 1
{
"error": "rate_limit_exceeded",
"message": "maximum requests",
"code": 429,
"endpoint": "/merchants/orders",
"total_requests": 101,
"retry_after": "1s"
}Response fields can differ when a gateway-wide safeguard rejects the request. Treat the HTTP status and Retry-After header as authoritative.
Handle 429 responses safely
- Stop sending requests for at least the number of seconds in
Retry-After. - Retry with exponential backoff and jitter instead of immediately releasing queued traffic as another burst.
- For the same payment operation, reuse the original idempotency key and the exact same request body.
- Coordinate throttling across workers and application instances; per-process retry loops can collectively exceed a shared merchant or endpoint limit.
- If
429responses continue after traffic is reduced, preserve the response body and request ID, then contact DEUNA Support or your Technical Account Manager (TAM).
Request a limit increase
Ask DEUNA Support or your TAM to review the limit before a planned traffic increase. Include:
- The environment and merchant ID.
- The affected HTTP methods and endpoints.
- Expected sustained and peak request rates, burst duration, and planned rollout date.
- The outbound (egress) public IP addresses or CIDRs used by the merchant systems that call DEUNA.
Do not include API keys, Bearer tokens, or other secrets in a support request.