curl --request GET \
--url https://api.getdialed.ai/v1/flows/jobs/exports/{export_id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}', 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.getdialed.ai/v1/flows/jobs/exports/{export_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"created_at": "2026-08-11T12:00:00Z",
"download_url": "https://example-bucket.s3.amazonaws.com/...",
"download_url_expires_at": "2026-08-11T12:15:00Z",
"expires_at": "2026-08-18T12:00:00Z",
"id": "exp_0123456789abcdef",
"row_count": 1284,
"status": "ready"
}{
"detail": "Authentication required"
}{
"detail": "Export not found"
}{
"detail": "This export has passed its 7-day deadline and the file has been deleted. Request the export again to regenerate it."
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"detail": "Rate limit exceeded: 100 per 1 minute"
}{
"detail": "CSV export is not available on this deployment. No export was created — contact support rather than retrying."
}Get an export and its download URL
Read one export. While the file is being generated the status is pending or running and download_url is null — that is a normal poll, not an error. Once the status is ready, the response carries a short-lived signed download_url.
The URL is deliberately short-lived and freely re-fetchable: read this endpoint again at any time for a fresh one, for as long as the export lives. So there is never a reason to store or share the URL itself.
If the export failed, error_reason says why. Once the file has passed its 7-day deadline it is deleted and this endpoint returns 410 — request a new export to regenerate it. An export belonging to another organization returns 404, never 403.
curl --request GET \
--url https://api.getdialed.ai/v1/flows/jobs/exports/{export_id} \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}', 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.getdialed.ai/v1/flows/jobs/exports/{export_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getdialed.ai/v1/flows/jobs/exports/{export_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"created_at": "2026-08-11T12:00:00Z",
"download_url": "https://example-bucket.s3.amazonaws.com/...",
"download_url_expires_at": "2026-08-11T12:15:00Z",
"expires_at": "2026-08-18T12:00:00Z",
"id": "exp_0123456789abcdef",
"row_count": 1284,
"status": "ready"
}{
"detail": "Authentication required"
}{
"detail": "Export not found"
}{
"detail": "This export has passed its 7-day deadline and the file has been deleted. Request the export again to regenerate it."
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"detail": "Rate limit exceeded: 100 per 1 minute"
}{
"detail": "CSV export is not available on this deployment. No export was created — contact support rather than retrying."
}Authorizations
Path Parameters
Response
Successful Response
An export and, once it is ready, how to download it.
status moves from pending to running while the file is generated, then
to ready — or to failed if the export could not be produced, in which
case error_reason says why. expired means the file has passed its
deletion deadline and is gone.
download_url is a short-lived signed URL that appears once the export is
ready. It expires quickly by design and is re-fetchable: read the export
again whenever you need a fresh URL. The file itself is deleted 7 days after
the export was created; after that, request the export again to regenerate it
from the underlying jobs, for as long as those jobs are inside your retention
window.
Identifier of this export.
Lifecycle state: pending, running, ready, failed, or expired once the file has passed its deletion deadline.
pending, running, ready, failed, expired When the export was requested.
When the generated file is deleted — 7 days after the export was requested.
Number of rows in the generated file. Null until the export is ready.
Why a failed export could not be produced: row_cap_exceeded when the filters matched more rows than one export may contain, source_unavailable when the records were no longer retained, or generation_failed. Null unless the export failed.
Short-lived signed download URL, present once the export is ready. Re-read the export to get a fresh one.
When this download URL stops working. The export itself lives until expires_at.