curl --request POST \
--url https://dally.ai/v1/send.approved \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"request_id": "e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5"
}
'import requests
url = "https://dally.ai/v1/send.approved"
payload = {
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"request_id": "e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
platform_account_id: '1234567890123456',
text: 'Thanks for asking! I film every Tuesday, so next week works.',
request_id: 'e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5'
})
};
fetch('https://dally.ai/v1/send.approved', 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://dally.ai/v1/send.approved",
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([
'platform_account_id' => '1234567890123456',
'text' => 'Thanks for asking! I film every Tuesday, so next week works.',
'request_id' => 'e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5'
]),
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://dally.ai/v1/send.approved"
payload := strings.NewReader("{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://dally.ai/v1/send.approved")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://dally.ai/v1/send.approved")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}"
response = http.request(request)
puts response.read_body{
"sent": {
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"tag": null,
"sent_at": "2026-09-19T15:00:05.000Z",
"provider_message_id": "aWdfZG1fOTk5",
"touchpoint_id": "3c1f0b7d-4a52-4e88-b6c3-1d7e9a204f61",
"connection_id": "7c1f0b7d-4a52-4e88-b6c3-1d7e9a204f62"
},
"show": {
"kind": "approved_send"
},
"request_id": "req_01j8zkq"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
},
"request_id": "<string>"
}send.approved
Access: public. Send a JSON body; unknown keys are rejected with 400 invalid_request (inputs are strict). Responses may gain fields additively — never remove or repurpose; ignore unknown response fields.
curl --request POST \
--url https://dally.ai/v1/send.approved \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"request_id": "e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5"
}
'import requests
url = "https://dally.ai/v1/send.approved"
payload = {
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"request_id": "e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
platform_account_id: '1234567890123456',
text: 'Thanks for asking! I film every Tuesday, so next week works.',
request_id: 'e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5'
})
};
fetch('https://dally.ai/v1/send.approved', 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://dally.ai/v1/send.approved",
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([
'platform_account_id' => '1234567890123456',
'text' => 'Thanks for asking! I film every Tuesday, so next week works.',
'request_id' => 'e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5'
]),
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://dally.ai/v1/send.approved"
payload := strings.NewReader("{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://dally.ai/v1/send.approved")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://dally.ai/v1/send.approved")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"platform_account_id\": \"1234567890123456\",\n \"text\": \"Thanks for asking! I film every Tuesday, so next week works.\",\n \"request_id\": \"e5e5e5e5-e5e5-4e5e-8e5e-e5e5e5e5e5e5\"\n}"
response = http.request(request)
puts response.read_body{
"sent": {
"platform_account_id": "1234567890123456",
"text": "Thanks for asking! I film every Tuesday, so next week works.",
"tag": null,
"sent_at": "2026-09-19T15:00:05.000Z",
"provider_message_id": "aWdfZG1fOTk5",
"touchpoint_id": "3c1f0b7d-4a52-4e88-b6c3-1d7e9a204f61",
"connection_id": "7c1f0b7d-4a52-4e88-b6c3-1d7e9a204f62"
},
"show": {
"kind": "approved_send"
},
"request_id": "req_01j8zkq"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
},
"request_id": "<string>"
}Authorizations
A WorkOS-dashboard-issued internal API key on Authorization: Bearer.
Body
The person's Instagram-scoped id, from the DM you are answering: touchpoints, kind dm, platform_account_id. Never a handle, never a display name.
1 - 64The message as the creator approved it, at most 1000 Unicode code points. It is sent exactly as written: Dally adds no link and no disclosure.
1 - 1000A UUID you mint for this one send. The same id twice sends one message, so carry the same id into a retry and mint a fresh one for a new message.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$The Instagram connection to send from. Omit it and Dally sends from the creator's live one, which is what every room with one account has.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Response
Success. request_id is present on every response.
One DM Dally sent as the creator because the creator read it here and asked for it.
Show child attributes
Show child attributes
How it is shown: dally_write renders the sent message on this very answer with this whole response as its data, so the creator already sees what went; do not render it again.
Show child attributes
Show child attributes
Server-minted id for this request. Present on every response, success and error — quote it when reporting a problem.
1