curl --request POST \
--url https://dally.ai/v1/open \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"window": 1
}
'import requests
url = "https://dally.ai/v1/open"
payload = {
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"window": 1
}
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({content_id: '3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43', window: 1})
};
fetch('https://dally.ai/v1/open', 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/open",
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_id' => '3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43',
'window' => 1
]),
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/open"
payload := strings.NewReader("{\n \"content_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\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/open")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://dally.ai/v1/open")
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_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\n}"
response = http.request(request)
puts response.read_body{
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"duration_seconds": 47.3,
"frame_count": 48,
"frame_width_px": 512,
"window_seconds": 20,
"dense_sheet_seconds": 4,
"dense_sheet_count": 12,
"windows": [
{
"index": 1,
"start_second": 0,
"end_second": 19,
"frame_count": 20
},
{
"index": 2,
"start_second": 20,
"end_second": 39,
"frame_count": 20
},
{
"index": 3,
"start_second": 40,
"end_second": 47,
"frame_count": 8
}
],
"images": [
{
"kind": "window",
"window": 1,
"key": "content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/sheets/20s/001.jpg",
"url": "https://media.withdally.com/content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/sheets/20s/001.jpg",
"mime_type": "image/jpeg",
"columns": 5,
"rows": 4,
"tile_width_px": 256,
"tiles": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19
]
}
],
"next": {
"window": 2
},
"standing": {
"ready": true,
"done": 14,
"total": 14,
"failed": [],
"note": "Complete: every part Dally reads out of this reel is in."
},
"rows": {
"fence": "untrusted_content_5f3a9c1e7b2d",
"wing": "pool",
"views": [
{
"view": "pool_content_transcripts",
"rows": [
{
"t_start": 0,
"t_end": 1.4,
"text": "<untrusted_content_5f3a9c1e7b2d>What do you say?</untrusted_content_5f3a9c1e7b2d>",
"word_count": 4,
"model": "<untrusted_content_5f3a9c1e7b2d>whisper-large-v3</untrusted_content_5f3a9c1e7b2d>",
"as_of": "<untrusted_content_5f3a9c1e7b2d>2026-09-19T15:43:11+00:00</untrusted_content_5f3a9c1e7b2d>",
"media_index": 0,
"voices": [
"A"
]
}
],
"served": 1,
"of": 1
}
]
},
"request_id": "req_01j8zkq"
}{
"kind": "working",
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"done": 9,
"total": 14,
"elapsed_seconds": 42,
"deadline_seconds": 180,
"call_again": true,
"note": "The reel is saved and still being read: 9 of 14 parts are finished. Call open again with the same url now.",
"request_id": "req_01j8zkr"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
},
"request_id": "<string>"
}open
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/open \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"window": 1
}
'import requests
url = "https://dally.ai/v1/open"
payload = {
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"window": 1
}
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({content_id: '3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43', window: 1})
};
fetch('https://dally.ai/v1/open', 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/open",
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_id' => '3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43',
'window' => 1
]),
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/open"
payload := strings.NewReader("{\n \"content_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\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/open")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"content_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://dally.ai/v1/open")
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_id\": \"3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43\",\n \"window\": 1\n}"
response = http.request(request)
puts response.read_body{
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"duration_seconds": 47.3,
"frame_count": 48,
"frame_width_px": 512,
"window_seconds": 20,
"dense_sheet_seconds": 4,
"dense_sheet_count": 12,
"windows": [
{
"index": 1,
"start_second": 0,
"end_second": 19,
"frame_count": 20
},
{
"index": 2,
"start_second": 20,
"end_second": 39,
"frame_count": 20
},
{
"index": 3,
"start_second": 40,
"end_second": 47,
"frame_count": 8
}
],
"images": [
{
"kind": "window",
"window": 1,
"key": "content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/sheets/20s/001.jpg",
"url": "https://media.withdally.com/content/3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43/frames/sheets/20s/001.jpg",
"mime_type": "image/jpeg",
"columns": 5,
"rows": 4,
"tile_width_px": 256,
"tiles": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19
]
}
],
"next": {
"window": 2
},
"standing": {
"ready": true,
"done": 14,
"total": 14,
"failed": [],
"note": "Complete: every part Dally reads out of this reel is in."
},
"rows": {
"fence": "untrusted_content_5f3a9c1e7b2d",
"wing": "pool",
"views": [
{
"view": "pool_content_transcripts",
"rows": [
{
"t_start": 0,
"t_end": 1.4,
"text": "<untrusted_content_5f3a9c1e7b2d>What do you say?</untrusted_content_5f3a9c1e7b2d>",
"word_count": 4,
"model": "<untrusted_content_5f3a9c1e7b2d>whisper-large-v3</untrusted_content_5f3a9c1e7b2d>",
"as_of": "<untrusted_content_5f3a9c1e7b2d>2026-09-19T15:43:11+00:00</untrusted_content_5f3a9c1e7b2d>",
"media_index": 0,
"voices": [
"A"
]
}
],
"served": 1,
"of": 1
}
]
},
"request_id": "req_01j8zkq"
}{
"kind": "working",
"content_id": "3b1f0c7a-9d24-4e51-b6c8-2f7a90d15e43",
"done": 9,
"total": 14,
"elapsed_seconds": 42,
"deadline_seconds": 180,
"call_again": true,
"note": "The reel is saved and still being read: 9 of 14 parts are finished. Call open again with the same url now.",
"request_id": "req_01j8zkr"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {}
},
"request_id": "<string>"
}Authorizations
A WorkOS-dashboard-issued internal API key on Authorization: Bearer.
Body
The Content to open: the content_id a query or search row carries.
^([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)$A public Instagram post URL. Choose url or content_id. A url admits the post, asks for everything Dally reads out of a reel, and waits for it to be complete: while it is not, the answer is the working answer, whose kind is working and which carries no pictures and no rows. While its call_again is true, call open again with the same url straight away and keep doing so — answer the person only from a complete result, never from a working one. When call_again is false the wait is over: tell the person the reel is saved and still processing, and to ask again in a few minutes.
2048Select one album slide to open, including a video slide. Omit it for the whole album.
x >= 0Open selected album slide positions, in the order given. Image slides arrive as pictures; a video slide is listed with its media_index, to open on its own.
1 - 100 elementsx >= 1Ask for the photo, all image slides of an album, or one video overview sheet. Album video slides are listed with their media_index so they can be opened separately.
Ask for every window sheet: one 20-tile sheet per 20-second window, one tile a second, 5 across. The whole reel readable beat by beat; one picture per window.
Ask for one window's sheet by number, from 1. The result names next, the window after it, until the reel ends.
x >= 1Ask for one dense sheet by number, from 1: four seconds of the reel as 20 tiles, every stored frame at five a second, 512 px each. The cheapest way to read what happens across a stretch; the result names next, the sheet after it.
x >= 1Exact stored 5-fps moments in seconds, such as [0, 0.2, 0.4]. One picture per moment; choose only what the question needs.
1 - 1000 elementsx >= 0Must be a multiple of 0.2Ask for exact frames at these seconds, 512 px wide, one picture each, in the order given (each second once). To look closely at a moment a sheet showed.
1A whole second into the reel, counted from 0.
x >= 0Response
Success. request_id is present on every response.
The Content opened, echoed.
^([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 reel's duration in seconds, as the frames were cut.
x >= 0How many per-second frames are stored: seconds 0 to frame_count - 1.
x >= 0The stored video frames' width in pixels; null for original image media, whose native dimensions vary.
x >= 1How many seconds one window spans.
x >= 1How many seconds one dense sheet spans; 0 when this reel's frames predate dense sheets.
x >= 0How many dense sheets the reel holds, so one can be asked for by number.
x >= 0Every window of the reel, so a window can be asked for by number.
Show child attributes
Show child attributes
The pictures this call serves, in the order their image blocks follow this text. Each carries the seconds it shows.
One picture the result carries: what it shows and where it lives. The image blocks after this text follow this list in order.
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
After a window or dense ask, the next one to ask for; null when the served sheet was the last, or when the ask was not one sheet.
- Option 1
- Option 2
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.
1Where this media's reading stands. Present for a video; an album overview carries none. Whatever the views already hold is served beside it, so a reel still being read answers with the rows that are in.
Show child attributes
Show child attributes
What the catalogue's views hold on this Content, read through the same views the query operation serves and fenced the same way. A voice is a sound the separator told apart, never a person; a row with two letters is two voices at once, a row with none is words no voice claimed, and no row says the account said anything.
Show child attributes
Show child attributes
0 for standalone media; an album slide position counted from 1.
x >= 0What the Content is: one image, an album of slides, or a video.
image, album, video Every media item at its original album position. Withheld media is unavailable from the provider; the rows carry each slide's media_index.
Show child attributes
Show child attributes
Stored frames per second; older Contents can have lower coverage.
Number of stored frames across the whole video.
Present when a video was opened by url and its wait is over: the answer about it ends as a canvas rendered through dally_show, with this reel as its Spotlight and your explanation beside it, then a brief takeaway in chat.
Show child attributes
Show child attributes
