curl --request PUT \
--url https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"rich_template_data": {
"name": "order-update",
"title": "Your order has shipped",
"body": "Track package {{tracking_id}}"
}
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}"
payload = { "rich_template_data": {
"name": "order-update",
"title": "Your order has shipped",
"body": "Track package {{tracking_id}}"
} }
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({
rich_template_data: {
name: 'order-update',
title: 'Your order has shipped',
body: JSON.stringify('Track package {{tracking_id}}')
}
})
};
fetch('https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}', 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.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}",
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([
'rich_template_data' => [
'name' => 'order-update',
'title' => 'Your order has shipped',
'body' => 'Track package {{tracking_id}}'
]
]),
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://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}"
payload := strings.NewReader("{\n \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\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://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}")
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 \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\n }\n}"
response = http.request(request)
puts response.read_body{}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "<string>",
"status": 429,
"retry_after": 2
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}Update RCS template
Replace a template’s definition. Send the complete { rich_template_data } — the update overwrites the stored card rather than merging individual fields — and keep the same name so existing references stay valid. Rich deep-link actions are validated the same way as on create. The template returns to pending approval after the change, so publish updates before a campaign depends on them.
curl --request PUT \
--url https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"rich_template_data": {
"name": "order-update",
"title": "Your order has shipped",
"body": "Track package {{tracking_id}}"
}
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}"
payload = { "rich_template_data": {
"name": "order-update",
"title": "Your order has shipped",
"body": "Track package {{tracking_id}}"
} }
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({
rich_template_data: {
name: 'order-update',
title: 'Your order has shipped',
body: JSON.stringify('Track package {{tracking_id}}')
}
})
};
fetch('https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}', 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.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}",
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([
'rich_template_data' => [
'name' => 'order-update',
'title' => 'Your order has shipped',
'body' => 'Track package {{tracking_id}}'
]
]),
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://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}"
payload := strings.NewReader("{\n \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\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://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/rcs/bots/{id}/templates/{name}")
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 \"rich_template_data\": {\n \"name\": \"order-update\",\n \"title\": \"Your order has shipped\",\n \"body\": \"Track package {{tracking_id}}\"\n }\n}"
response = http.request(request)
puts response.read_body{}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "<string>",
"status": 429,
"retry_after": 2
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}Authorizations
Dashboard JWT token from Clerk
Headers
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
1 - 255Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
true, false Body
The body is of type object.
Response
The updated template as returned by the RCS platform, wrapped in the standard { data, meta } envelope. Its approval status is back to pending.
The updated template as returned by the RCS platform, wrapped in the standard { data, meta } envelope. Its approval status is back to pending.