Python
# Reserves the upload, sends the bytes with the exact upload_headers, returns the reference
media = niadra.upload_media(audio_bytes, "audio/ogg", subject=phone("+14155550123"))
niadra.track({
"channel": "whatsapp",
"conversation_id": "wa-8812",
"handles": [phone("+14155550123")],
"speaker": {"role": "customer"},
"content": {"type": "audio", "media_ref": media.media_ref, "media_sha256": media.media_sha256},
})// Reserves the upload, sends the bytes with the exact upload_headers, returns the reference
const { data: media } = await niadra.uploadMedia({
data: audioBytes,
content_type: "audio/ogg",
subject: handles.phone("+14155550123"),
});
niadra.track({
channel: "whatsapp",
conversation_id: "wa-8812",
handles: [handles.phone("+14155550123")],
speaker: "customer",
content: { type: "audio", media_ref: media!.media_ref, media_sha256: media!.media_sha256 },
});curl --request POST \
--url https://{space}.{region}.api.niadra.com/v1/media/uploads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content_type": "audio/ogg",
"size_bytes": 48213,
"sha256": "a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90",
"subject": {
"type": "phone_e164",
"value": "+14155550123"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
content_type: 'audio/ogg',
size_bytes: 48213,
sha256: 'a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90',
subject: {type: 'phone_e164', value: '+14155550123'}
})
};
fetch('https://{space}.{region}.api.niadra.com/v1/media/uploads', 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://{space}.{region}.api.niadra.com/v1/media/uploads",
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([
'content_type' => 'audio/ogg',
'size_bytes' => 48213,
'sha256' => 'a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90',
'subject' => [
'type' => 'phone_e164',
'value' => '+14155550123'
]
]),
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://{space}.{region}.api.niadra.com/v1/media/uploads"
payload := strings.NewReader("{\n \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\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://{space}.{region}.api.niadra.com/v1/media/uploads")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{space}.{region}.api.niadra.com/v1/media/uploads")
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 \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"media_ref": "med_01J8ZM2",
"upload_url": "https://uploads.us-east-1.api.niadra.com/med_01J8ZM2?sig=...",
"upload_headers": {
"Content-Type": "audio/ogg",
"x-amz-checksum-sha256": "o/HC1OW2l4gSqzTNVu94kKGyw9Tl9gcYKTpLXG1+j5A="
},
"expires_at": "2026-09-22T17:17:03Z"
}{
"code": "<string>",
"status": 123,
"title": "<string>",
"detail": "<string>",
"request_id": "<string>",
"type": "about:blank"
}Write
Request a media upload
A presigned URL and the exact upload headers; the event carries only the reference and the hash.
POST
/
v1
/
media
/
uploads
Python
# Reserves the upload, sends the bytes with the exact upload_headers, returns the reference
media = niadra.upload_media(audio_bytes, "audio/ogg", subject=phone("+14155550123"))
niadra.track({
"channel": "whatsapp",
"conversation_id": "wa-8812",
"handles": [phone("+14155550123")],
"speaker": {"role": "customer"},
"content": {"type": "audio", "media_ref": media.media_ref, "media_sha256": media.media_sha256},
})// Reserves the upload, sends the bytes with the exact upload_headers, returns the reference
const { data: media } = await niadra.uploadMedia({
data: audioBytes,
content_type: "audio/ogg",
subject: handles.phone("+14155550123"),
});
niadra.track({
channel: "whatsapp",
conversation_id: "wa-8812",
handles: [handles.phone("+14155550123")],
speaker: "customer",
content: { type: "audio", media_ref: media!.media_ref, media_sha256: media!.media_sha256 },
});curl --request POST \
--url https://{space}.{region}.api.niadra.com/v1/media/uploads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content_type": "audio/ogg",
"size_bytes": 48213,
"sha256": "a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90",
"subject": {
"type": "phone_e164",
"value": "+14155550123"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
content_type: 'audio/ogg',
size_bytes: 48213,
sha256: 'a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90',
subject: {type: 'phone_e164', value: '+14155550123'}
})
};
fetch('https://{space}.{region}.api.niadra.com/v1/media/uploads', 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://{space}.{region}.api.niadra.com/v1/media/uploads",
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([
'content_type' => 'audio/ogg',
'size_bytes' => 48213,
'sha256' => 'a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90',
'subject' => [
'type' => 'phone_e164',
'value' => '+14155550123'
]
]),
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://{space}.{region}.api.niadra.com/v1/media/uploads"
payload := strings.NewReader("{\n \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\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://{space}.{region}.api.niadra.com/v1/media/uploads")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{space}.{region}.api.niadra.com/v1/media/uploads")
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 \"content_type\": \"audio/ogg\",\n \"size_bytes\": 48213,\n \"sha256\": \"a3f1c2d4e5b6978812ab34cd56ef7890a1b2c3d4e5f60718293a4b5c6d7e8f90\",\n \"subject\": {\n \"type\": \"phone_e164\",\n \"value\": \"+14155550123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"media_ref": "med_01J8ZM2",
"upload_url": "https://uploads.us-east-1.api.niadra.com/med_01J8ZM2?sig=...",
"upload_headers": {
"Content-Type": "audio/ogg",
"x-amz-checksum-sha256": "o/HC1OW2l4gSqzTNVu94kKGyw9Tl9gcYKTpLXG1+j5A="
},
"expires_at": "2026-09-22T17:17:03Z"
}{
"code": "<string>",
"status": 123,
"title": "<string>",
"detail": "<string>",
"request_id": "<string>",
"type": "about:blank"
}Authorizations
nia_sk_...
Body
application/json
Required string length:
1 - 256Pattern:
^[0-9a-f]{64}$Required range:
x <= 524288000Whose media it is. The object is stored under the subject's handle, so forget reaches it even if no event ever references it.
Show child attributes
Show child attributes
Response
The upload slot, valid until expires_at.

