curl --request PUT \
--url https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"fallbacks": [
{
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model": "<string>"
}
],
"routing": {
"fail_over_on": [],
"attempt_timeout_s": 305,
"total_budget_s": 455,
"first_token_timeout_s": 60,
"breaker_enabled": true,
"same_residency": true
}
}
'import requests
url = "https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks"
payload = {
"fallbacks": [
{
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model": "<string>"
}
],
"routing": {
"fail_over_on": [],
"attempt_timeout_s": 305,
"total_budget_s": 455,
"first_token_timeout_s": 60,
"breaker_enabled": True,
"same_residency": True
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fallbacks: [{provider_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', model: '<string>'}],
routing: {
fail_over_on: [],
attempt_timeout_s: 305,
total_budget_s: 455,
first_token_timeout_s: 60,
breaker_enabled: true,
same_residency: true
}
})
};
fetch('https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks', 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://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'fallbacks' => [
[
'provider_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'model' => '<string>'
]
],
'routing' => [
'fail_over_on' => [
],
'attempt_timeout_s' => 305,
'total_budget_s' => 455,
'first_token_timeout_s' => 60,
'breaker_enabled' => true,
'same_residency' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks"
payload := strings.NewReader("{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"system_prompt": "<string>",
"status": "draft",
"source": "auto",
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"provider": "<string>",
"model": "<string>"
},
"agent_url": "<string>",
"deployment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"fallbacks": [
{
"position": 123,
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"provider": "<string>",
"model": "<string>"
},
"model": "<string>",
"model_override": "<string>",
"residency": "unknown",
"capabilities": {
"context_window": 123,
"max_output": 123,
"vision": true,
"tools": true,
"reasoning": true
}
}
],
"routing": {
"fail_over_on": [
"unreachable"
],
"attempt_timeout_s": 120,
"total_budget_s": 300,
"first_token_timeout_s": 60,
"breaker_enabled": true,
"same_residency": false
},
"primary_capabilities": {
"context_window": 123,
"max_output": 123,
"vision": true,
"tools": true,
"reasoning": true
},
"primary_residency": "unknown"
}Replace an agent's fallback providers
Replace the whole ordered list of fallback providers (positions 1..N
in the order sent, at most 3) and, when sent, the failover settings
(routing, merged onto the current ones; null resets them).
Each fallback is one of the organisation’s provider connections, with an
optional model override. A refused change answers a detail object
with a stable code and changes nothing. The agent’s config version
(and credential version) advances, so the runtime picks the chain up.
curl --request PUT \
--url https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"fallbacks": [
{
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model": "<string>"
}
],
"routing": {
"fail_over_on": [],
"attempt_timeout_s": 305,
"total_budget_s": 455,
"first_token_timeout_s": 60,
"breaker_enabled": true,
"same_residency": true
}
}
'import requests
url = "https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks"
payload = {
"fallbacks": [
{
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model": "<string>"
}
],
"routing": {
"fail_over_on": [],
"attempt_timeout_s": 305,
"total_budget_s": 455,
"first_token_timeout_s": 60,
"breaker_enabled": True,
"same_residency": True
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fallbacks: [{provider_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', model: '<string>'}],
routing: {
fail_over_on: [],
attempt_timeout_s: 305,
total_budget_s: 455,
first_token_timeout_s: 60,
breaker_enabled: true,
same_residency: true
}
})
};
fetch('https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks', 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://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'fallbacks' => [
[
'provider_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'model' => '<string>'
]
],
'routing' => [
'fail_over_on' => [
],
'attempt_timeout_s' => 305,
'total_budget_s' => 455,
'first_token_timeout_s' => 60,
'breaker_enabled' => true,
'same_residency' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks"
payload := strings.NewReader("{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://cp.xenovia.io/api/v1/agents/{agent_id}/fallbacks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fallbacks\": [\n {\n \"provider_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"model\": \"<string>\"\n }\n ],\n \"routing\": {\n \"fail_over_on\": [],\n \"attempt_timeout_s\": 305,\n \"total_budget_s\": 455,\n \"first_token_timeout_s\": 60,\n \"breaker_enabled\": true,\n \"same_residency\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"owner_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"system_prompt": "<string>",
"status": "draft",
"source": "auto",
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"provider": "<string>",
"model": "<string>"
},
"agent_url": "<string>",
"deployment_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"fallbacks": [
{
"position": 123,
"provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"provider": "<string>",
"model": "<string>"
},
"model": "<string>",
"model_override": "<string>",
"residency": "unknown",
"capabilities": {
"context_window": 123,
"max_output": 123,
"vision": true,
"tools": true,
"reasoning": true
}
}
],
"routing": {
"fail_over_on": [
"unreachable"
],
"attempt_timeout_s": 120,
"total_budget_s": 300,
"first_token_timeout_s": 60,
"breaker_enabled": true,
"same_residency": false
},
"primary_capabilities": {
"context_window": 123,
"max_output": 123,
"vision": true,
"tools": true,
"reasoning": true
},
"primary_residency": "unknown"
}Authorizations
Bearer token: an organization API key (ak_…) created under Settings → API Keys, or a dashboard user session token. Agent keys (xe_…) are not accepted here. Endpoints marked as user-only in their description reject organization keys with 403.
Headers
Path Parameters
Body
PUT /agents/{agent_id}/fallbacks: the whole ordered list (positions
1..N in this order) and, optionally, routing. Omitting routing keeps
it; null resets it to the defaults.
Response
Successful Response
draft, active auto, manual Show child attributes
Show child attributes
Endpoint base URL for this agent. Cloud agents render https://runtime.xenovia.io/{agent_id}/v1; hybrid agents render their deployment's ingress URL plus /{agent_id}/v1.
Show child attributes
Show child attributes
An agent's failover settings, always whole (every default filled).
Show child attributes
Show child attributes
What a model can take, from the public model directory (models.dev); each member is null when the directory does not say (assume capable).
Show child attributes
Show child attributes
us, eu, apac, global, unknown