Authentication and API keys
Use DEUNA public and private API keys in the correct client, server, merchant, and environment context.
On this page
DEUNA credentials identify the merchant and environment used by an integration. The required authorization depends on the endpoint and the caller, so check the authorization panel in the endpoint catalog before implementing a request.
Choose the correct credential#
| Credential | Where it belongs | What it does |
|---|---|---|
| Public API key | Browser or mobile SDK | Initializes supported client-side UI and tokenization flows. |
| Private API key | Trusted merchant backend | Authorizes merchant server-to-server operations through X-Api-Key. |
| Customer access token | Customer-facing flow | Adds signed-in customer context through Authorization: Bearer … on endpoints that support it. |
| Admin session | DEUNA Admin | Gives an authorized operator role-based access; it is not an integration API credential. |
Merchant-backend authorization#
Merchant operations that use API-key authorization expect the private key in X-Api-Key.
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))
}Some endpoints also accept an Authorization header to carry customer identity:
Authorization: Bearer USER_ACCESS_TOKENThe Bearer token does not replace a required private API key. Send it only when the endpoint documents Bearer support and the operation needs authenticated-customer context, such as stored instruments or customer-specific payment methods.
Environments#
Sandbox and production are isolated. Each environment has its own base URL, API keys, merchant configuration, connections, data, and webhook endpoints.
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#
When an authenticated request exceeds its allowed request rate, the API returns 429 Too Many Requests. Honor Retry-After when it is present, back off instead of sending a burst of retries, and reuse the original idempotency key and body for the same payment attempt. Limits can vary by account and endpoint.