TypeScript SDK
@retorna-tech/retorna-gateway-sdk (npm, 1.0.4) ships as both ESM and CJS,
with native TypeScript types — no separate @types package to install. It
takes token exchange, request signing, retries, and identity headers off your
plate, and hands you back typed models for every call.
Install
Requires Node >=18.18.0.
pnpm add @retorna-tech/retorna-gateway-sdk
# or
npm install @retorna-tech/retorna-gateway-sdk
# or
yarn add @retorna-tech/retorna-gateway-sdk
Build a client
The builder is RetornaClientBuilder, the same name the Python and Java SDKs use. The previous RetornaTypeScriptSDKConfigBuilder still works as a deprecated alias and goes away in 2.0.
import {
RetornaClientBuilder,
RetornaEnvironment,
} from "@retorna-tech/retorna-gateway-sdk";
const client = new RetornaClientBuilder()
.environment(RetornaEnvironment.SANDBOX)
.clientId(process.env.RETORNA_CLIENT_ID!)
.clientSecret(process.env.RETORNA_CLIENT_SECRET!)
.privateKey(process.env.RETORNA_PRIVATE_KEY!) // PEM RSA, newlines intact
.buildClient();
const me = await client.getMyClient();
console.log(me.client.name, me.client.isActive);
| Variable | What it holds |
|---|---|
RETORNA_CLIENT_ID | Client ID issued during provisioning. |
RETORNA_CLIENT_SECRET | Client secret issued during provisioning. |
RETORNA_PRIVATE_KEY | PEM RSA private key used to sign every request — keep the newlines intact. |
getMyClient() reads the company tied to your credentials — there is no
ownerId to pass, the token already scopes it. buildClient() is the
terminal call: it returns the ready-to-use client. Miss a required field and
the builder throws before any network call is made.
Configuration
| Option | Method | Required | Default | Notes |
|---|---|---|---|---|
| Environment | .environment(env) | Yes | — | RetornaEnvironment.DEVELOP | SANDBOX | PRODUCTION |
| Client ID | .clientId(value) | Yes | — | Issued during provisioning |
| Client secret | .clientSecret(value) | Yes | — | Issued during provisioning |
| Private key | .privateKey(value) | Yes | — | PEM RSA key used to sign every request |
| Scope | .scope(value) | No | Environment default | Overrides the OAuth2 scope requested |
| Base URL override | .baseUrlOverride(url) | No | Environment default | Must start with https:// |
| Logging level | .loggingLevel(level) | No | — | One of none, error, warn, info, debug |
| Disable logging | .disableLogging() | No | Logging enabled | Turns the SDK's own logger off entirely |
| Retries | .retries(count) | No | 3 | Attempts on transient failures |
| Backoff | .backoffMs(ms) | No | 200 | Base backoff between retries, in milliseconds |
Every chain ends in .buildClient().
Environments
enum RetornaEnvironment {
DEVELOP = "develop",
SANDBOX = "sandbox",
PRODUCTION = "production",
}
Every example on this page runs against RetornaEnvironment.SANDBOX, which
resolves to https://api.gateway.sandbox.retorna.app. Production resolves to
https://api.gateway.retorna.app. DEVELOP is for internal use only.
Every request the SDK sends carries X-Retorna-Client: typescript-sdk/1.0.4
and a matching User-Agent, so the platform — and our support team, if you
ever need it — can tell which SDK and version made the call.
Authentication and signing
The SDK acquires and caches your OAuth2 token, and signs every request with your private key — you never touch the token endpoint or build the signing string yourself. See authentication and request signing for what happens under the hood.
Objects
Every method is documented in full — signatures, parameters, return models, and errors — on its own object page:
Quotations lock in an exchange rate, fees,
and resulting amounts for a corridor before you commit to sending —
createQuotation and getQuotation.
Orders spend a quotation and execute a payout
to a named beneficiary — createOrder, listOrders, and getOrder.
Routes list the corridors currently available
to your company, with their quoted rate, fees, and limits — getRoutes.
Wallets hold the USDR balance that funds your
orders — getMyWallet and getMyWalletTransactions.
Client is your own company record as the API
sees it — getMyClient.
Quote and send
const quotation = await client.createQuotation({
source: { currency: "USDR" },
destination: {
country: "VE",
currency: "VES",
payout_method: { type: "P2P_PHONE_TRANSFER" },
},
quote: { mode: "SEND_EXACT", amount: "10.00" },
});
const order = await client.createOrder(
{
quotation_id: quotation.id,
purpose: "FAMILY_SUPPORT",
sender: {
names: "Ana María",
last_names: "Pérez Gómez",
document: { type: "CC", id: "1020304050", country: "CO" },
country: "CO",
},
destination: {
receiver: {
names: "Carlos Andrés",
last_names: "Rodríguez López",
document: { type: "V", id: "12345678", country: "VE" },
country: "VE",
},
payment_instructions: {
bank_phone_account: {
bank_name: "BNC_VE",
phone_number: "+584121234567",
document_id: "12345678",
},
},
},
},
"invoice-2026-00456", // idempotency key — comes back as order.idempotency_key
);
console.log(order.id, order.status, order.idempotency_key);
A quote is locked in by createQuotation, then spent
by exactly one createOrder call — see quotations
and orders for every field, error, and pitfall,
including the idempotency key semantics and the closed bank catalog behind
bank_name.
Errors
import { RetornaB2BError, RetornaSdkError } from "@retorna-tech/retorna-gateway-sdk";
try {
await client.createOrder(request, "invoice-2026-00456");
} catch (err) {
if (err instanceof RetornaB2BError) {
console.error(err.code, err.category, err.httpStatus, err.correlationId);
if (err.code === "B2B_QUOTATION_EXPIRED") return requote();
if (err.category === "TRANSIENT") return retryWithSameKey();
throw err; // PERMANENT — fix the request first
}
if (err instanceof RetornaSdkError) {
console.error(err.context, err.message); // local validation or transport
}
throw err;
}
RetornaB2BError is the API's typed error envelope; RetornaSdkError covers
everything else the SDK itself catches — a failed builder validation, or a
response that never made it into that envelope shape. The full catalog of
codes lives in error codes, and the
different shapes an error body can take are explained in
handling errors. A retry of createOrder is only safe
with the same idempotency key as the original attempt.
Reports
The SDK also exposes a full reports client — creating, listing, downloading, and scheduling report generations and deliveries. It is out of scope for this page; see the SDK repository for its README and type definitions.
Next steps
- Every endpoint the SDK wraps has a full request/response example and a "Try it" panel in the API Reference.
- Prefer raw HTTP? The quickstart walks the same calls without the SDK.