Routing
Create a Routing
Creates a routing for one (account_code, payment_method) pair. Always live on success.
POST
/
routing
Create a Routing
curl --request POST \
--url https://api-sandbox.y.uno/v1/routing \
--header 'Content-Type: application/json' \
--header 'PRIVATE-SECRET-KEY: <api-key>' \
--header 'PUBLIC-API-KEY: <api-key>' \
--header 'X-Idempotency-Key: <x-idempotency-key>' \
--data '
{
"account_id": "7825fc5e-e50a-4248-9ae8-5d3786afb0be",
"payment_method": "CARD",
"name": "Card routing",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e"
}
]
}
}
'import requests
url = "https://api-sandbox.y.uno/v1/routing"
payload = {
"account_id": "7825fc5e-e50a-4248-9ae8-5d3786afb0be",
"payment_method": "CARD",
"name": "Card routing",
"default_route": { "steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e"
}
] }
}
headers = {
"X-Idempotency-Key": "<x-idempotency-key>",
"PUBLIC-API-KEY": "<api-key>",
"PRIVATE-SECRET-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Idempotency-Key': '<x-idempotency-key>',
'PUBLIC-API-KEY': '<api-key>',
'PRIVATE-SECRET-KEY': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
account_id: '7825fc5e-e50a-4248-9ae8-5d3786afb0be',
payment_method: 'CARD',
name: 'Card routing',
default_route: {
steps: [
{
index: 1,
provider_id: 'STRIPE',
connection_id: 'f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e'
}
]
}
})
};
fetch('https://api-sandbox.y.uno/v1/routing', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.y.uno/v1/routing",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'account_id' => '7825fc5e-e50a-4248-9ae8-5d3786afb0be',
'payment_method' => 'CARD',
'name' => 'Card routing',
'default_route' => [
'steps' => [
[
'index' => 1,
'provider_id' => 'STRIPE',
'connection_id' => 'f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"PRIVATE-SECRET-KEY: <api-key>",
"PUBLIC-API-KEY: <api-key>",
"X-Idempotency-Key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.y.uno/v1/routing"
payload := strings.NewReader("{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Idempotency-Key", "<x-idempotency-key>")
req.Header.Add("PUBLIC-API-KEY", "<api-key>")
req.Header.Add("PRIVATE-SECRET-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.y.uno/v1/routing")
.header("X-Idempotency-Key", "<x-idempotency-key>")
.header("PUBLIC-API-KEY", "<api-key>")
.header("PRIVATE-SECRET-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.y.uno/v1/routing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Idempotency-Key"] = '<x-idempotency-key>'
request["PUBLIC-API-KEY"] = '<api-key>'
request["PRIVATE-SECRET-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "r_8f2c1d3e-4b5a-6c7d-8e9f-0a1b2c3d4e5f",
"account_code": "acc-uuid",
"payment_method": "CARD",
"name": "Card routing",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-..."
}
]
},
"condition_sets": [
{
"sort_number": 1,
"name": "High Value US",
"conditions": [
{}
],
"route": {}
}
],
"created_at": "2026-05-12T14:30:00Z",
"updated_at": "2026-05-12T14:30:00Z",
"warnings": [
"MONITOR_REDISTRIBUTION_DEFERRED"
]
}{
"type": "validation_error",
"code": "ROUTING_VALIDATION_FAILED",
"message": "Steps must be contiguous"
}{
"type": "conflict",
"code": "ROUTING_ALREADY_EXISTS",
"message": "A routing already exists for this payment method"
}Creates a routing for one
(account_code, payment_method) pair. Each routing references connections by their connection_id. Make sure your connections are created and ACTIVE for the requested payment_method before you call routing.
Body
The merchant account ID this routing rule applies to.
E.g.,
CARD, PIX, WALLET. Immutable per routing — to route a different method, create a new routing.Free-form label.
The route used when no
condition_sets[] matches.Show properties
Show properties
Each step is one provider attempt.
index values are contiguous starting at 1.Show item
Show item
Step ordinal.
Must match the provider of the connection.
Must be
ACTIVE and support the payment_method.Defines how to handle each possible outcome of this step.
Show item
Show item
The outcome status that triggers this rule (e.g.,
APPROVED, DECLINED, DECLINE_GROUP, TIMEOUT, INTERNAL_ERROR).Required when
status is DECLINE_GROUP. Specifies which decline subtypes trigger this rule (e.g., INSUFFICIENT_FUNDS, DECLINED_BY_BANK).The
index of the next step to execute. Omit if no fallback is needed.Optional. Ordered by
sort_number — first matching set wins.Show item
Show item
Priority of the condition set.
Label for the set.
List of Conditions that must match.
The steps to execute if this set matches.
Response
Unique identifier for the routing.
Unique code for the account.
The payment method this routing applies to (e.g.,
CARD).Label for the routing.
The default routing logic.
Optional conditional logic.
ISO 8601 timestamp.
ISO 8601 timestamp.
curl -X POST 'https://api.y.uno/v1/routing' \
-H 'public-api-key: <YOUR_PUBLIC_KEY>' \
-H 'private-secret-key: <YOUR_SECRET_KEY>' \
-H 'Content-Type: application/json' \
-H 'X-Idempotency-Key: <UUID>' \
-d '{
"account_id": "7825fc5e-e50a-4248-9ae8-5d3786afb0be",
"payment_method": "CARD",
"name": "Card routing — Stripe primary, Adyen fallback",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e",
"output": [
{
"status": "DECLINE_GROUP",
"decline_types": ["DECLINED_BY_BANK", "DO_NOT_HONOR"],
"next": 2
},
{ "status": "TIMEOUT", "next": 2 },
{ "status": "INTERNAL_ERROR", "next": 2 }
]
},
{
"index": 2,
"provider_id": "ADYEN",
"connection_id": "b2c4d5e6-1a2b-3c4d-5e6f-7a8b9c0d1e2f"
}
]
},
"condition_sets": [
{
"sort_number": 1,
"name": "Brazil — 3 to 6 installments via Adyen",
"description": "BR card transactions with 3–6 installments go to Adyen directly",
"conditions": [
{ "condition_type": "COUNTRY", "conditional": "EQUAL", "values": ["BR"] },
{ "condition_type": "INSTALLMENTS", "conditional": "BETWEEN", "values": ["3", "6"] }
],
"route": {
"steps": [
{ "index": 1, "provider_id": "ADYEN", "connection_id": "b2c4d5e6-..." }
]
}
}
]
}'
{
"id": "r_8f2c1d3e-4b5a-6c7d-8e9f-0a1b2c3d4e5f",
"account_code": "acc-uuid",
"payment_method": "CARD",
"name": "Card routing — Stripe primary, Adyen fallback",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e",
"output": [
{ "status": "DECLINE_GROUP", "next": 2 },
{ "status": "TIMEOUT", "next": 2 }
]
},
{ "index": 2, "provider_id": "ADYEN", "connection_id": "b2c4d5e6-..." }
]
},
"condition_sets": [
{
"sort_number": 1,
"name": "Brazil — 3 to 6 installments via Adyen",
"conditions": [
{ "condition_type": "COUNTRY", "conditional": "EQUAL", "values": ["BR"] }
],
"route": { "steps": ["..."] }
}
],
"created_at": "2026-05-12T14:30:00Z",
"updated_at": "2026-05-12T14:30:00Z"
}
{
"type": "validation_error",
"code": "ROUTING_VALIDATION_FAILED",
"message": "default_route.steps[].index must be contiguous starting at 1",
"details": { "path": "default_route.steps[1].index", "expected": 2, "received": 3 }
}
{
"type": "conflict",
"code": "ROUTING_ALREADY_EXISTS",
"message": "A routing already exists for account 'acc-uuid' and payment_method 'CARD'",
"details": { "payment_method": "CARD", "existing_routing_id": "r_..." }
}
Errors
| HTTP | code | When |
|---|---|---|
400 | ROUTING_VALIDATION_FAILED | Schema or rule violation. details names the offending field/path. |
400 | ROUTING_PROVIDER_NOT_AVAILABLE | A step references a (provider_id, connection_id) not active for the account on this payment_method. |
409 | ROUTING_ALREADY_EXISTS | A routing already exists for this (account, payment_method). Use PATCH to update it. |
403 | INSUFFICIENT_SCOPE | API key missing routing:write. |
Authorizations
Headers
Body
application/json
Response
Created
Example:
"r_8f2c1d3e-4b5a-6c7d-8e9f-0a1b2c3d4e5f"
Example:
"acc-uuid"
Example:
"CARD"
Example:
"Card routing"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Example:
"2026-05-12T14:30:00Z"
Example:
"2026-05-12T14:30:00Z"
Example:
["MONITOR_REDISTRIBUTION_DEFERRED"]
Was this page helpful?
⌘I
Create a Routing
curl --request POST \
--url https://api-sandbox.y.uno/v1/routing \
--header 'Content-Type: application/json' \
--header 'PRIVATE-SECRET-KEY: <api-key>' \
--header 'PUBLIC-API-KEY: <api-key>' \
--header 'X-Idempotency-Key: <x-idempotency-key>' \
--data '
{
"account_id": "7825fc5e-e50a-4248-9ae8-5d3786afb0be",
"payment_method": "CARD",
"name": "Card routing",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e"
}
]
}
}
'import requests
url = "https://api-sandbox.y.uno/v1/routing"
payload = {
"account_id": "7825fc5e-e50a-4248-9ae8-5d3786afb0be",
"payment_method": "CARD",
"name": "Card routing",
"default_route": { "steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e"
}
] }
}
headers = {
"X-Idempotency-Key": "<x-idempotency-key>",
"PUBLIC-API-KEY": "<api-key>",
"PRIVATE-SECRET-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Idempotency-Key': '<x-idempotency-key>',
'PUBLIC-API-KEY': '<api-key>',
'PRIVATE-SECRET-KEY': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
account_id: '7825fc5e-e50a-4248-9ae8-5d3786afb0be',
payment_method: 'CARD',
name: 'Card routing',
default_route: {
steps: [
{
index: 1,
provider_id: 'STRIPE',
connection_id: 'f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e'
}
]
}
})
};
fetch('https://api-sandbox.y.uno/v1/routing', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-sandbox.y.uno/v1/routing",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'account_id' => '7825fc5e-e50a-4248-9ae8-5d3786afb0be',
'payment_method' => 'CARD',
'name' => 'Card routing',
'default_route' => [
'steps' => [
[
'index' => 1,
'provider_id' => 'STRIPE',
'connection_id' => 'f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"PRIVATE-SECRET-KEY: <api-key>",
"PUBLIC-API-KEY: <api-key>",
"X-Idempotency-Key: <x-idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-sandbox.y.uno/v1/routing"
payload := strings.NewReader("{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Idempotency-Key", "<x-idempotency-key>")
req.Header.Add("PUBLIC-API-KEY", "<api-key>")
req.Header.Add("PRIVATE-SECRET-KEY", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-sandbox.y.uno/v1/routing")
.header("X-Idempotency-Key", "<x-idempotency-key>")
.header("PUBLIC-API-KEY", "<api-key>")
.header("PRIVATE-SECRET-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-sandbox.y.uno/v1/routing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Idempotency-Key"] = '<x-idempotency-key>'
request["PUBLIC-API-KEY"] = '<api-key>'
request["PRIVATE-SECRET-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"account_id\": \"7825fc5e-e50a-4248-9ae8-5d3786afb0be\",\n \"payment_method\": \"CARD\",\n \"name\": \"Card routing\",\n \"default_route\": {\n \"steps\": [\n {\n \"index\": 1,\n \"provider_id\": \"STRIPE\",\n \"connection_id\": \"f1a3c4d5-7b8e-4a2c-9d1e-3f4a5b6c7d8e\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "r_8f2c1d3e-4b5a-6c7d-8e9f-0a1b2c3d4e5f",
"account_code": "acc-uuid",
"payment_method": "CARD",
"name": "Card routing",
"default_route": {
"steps": [
{
"index": 1,
"provider_id": "STRIPE",
"connection_id": "f1a3c4d5-..."
}
]
},
"condition_sets": [
{
"sort_number": 1,
"name": "High Value US",
"conditions": [
{}
],
"route": {}
}
],
"created_at": "2026-05-12T14:30:00Z",
"updated_at": "2026-05-12T14:30:00Z",
"warnings": [
"MONITOR_REDISTRIBUTION_DEFERRED"
]
}{
"type": "validation_error",
"code": "ROUTING_VALIDATION_FAILED",
"message": "Steps must be contiguous"
}{
"type": "conflict",
"code": "ROUTING_ALREADY_EXISTS",
"message": "A routing already exists for this payment method"
}