Long-form video ads (60s+) are increasingly common, but they're hard to spot in a feed that mixes them with 6-second bumpers. This recipe pulls just the long-form videos in a given category, ranked by how long they've been running — a rough proxy for "what's working."
Endpoints used
GET /open/v1/ads— search the global catalogGET /open/v1/ads/{ad_id}— fetch full detail for a single ad
New to the API? See the Quickstart for auth and the response envelope.
Step 1 — Find long-form video ads in a category
Filter the catalog to videos at least 60 seconds long, in your category of interest, ranked by how long each ad has been running:
curl -sS \
-H "X-API-Key: $ATRIA_API_KEY" \
"https://api.tryatria.com/open/v1/ads?display_format=video&video_length=60-120&video_length=120-&industry=electronics&sort_by=most_active&page_size=20"import os
import requests
resp = requests.get(
"https://api.tryatria.com/open/v1/ads",
headers={"X-API-Key": os.environ["ATRIA_API_KEY"]},
params=[
("display_format", "video"),
# Repeatable: include both 1-2min and 2min+ buckets
("video_length", "60-120"),
("video_length", "120-"),
("industry", "electronics"),
("sort_by", "most_active"),
("page_size", 20),
],
timeout=30,
)
for ad in resp.json()["data"]["items"]:
v = ad["videos"][0] if ad["videos"] else {}
print(
f"{ad['id']:<20} "
f"{int(v.get('duration', 0)):>3}s "
f"{ad['brand_name']:<30} "
f"{ad['title']}"
)const url = new URL("https://api.tryatria.com/open/v1/ads");
url.searchParams.set("display_format", "video");
// Repeatable: append both buckets
url.searchParams.append("video_length", "60-120");
url.searchParams.append("video_length", "120-");
url.searchParams.set("industry", "electronics");
url.searchParams.set("sort_by", "most_active");
url.searchParams.set("page_size", "20");
const resp = await fetch(url, {
headers: { "X-API-Key": process.env.ATRIA_API_KEY },
});
const { data } = await resp.json();
for (const ad of data.items) {
const v = ad.videos[0] ?? {};
console.log(
`${ad.id.padEnd(20)} ` +
`${String(Math.round(v.duration ?? 0)).padStart(3)}s ` +
`${(ad.brand_name ?? "").padEnd(30)} ` +
`${ad.title ?? ""}`,
);
}Each row prints the ad's id (an m... or t... identifier) — pick one you want to inspect and move to Step 2.
Step 2 — Pull full detail for an ad
Once you've spotted an interesting ad in Step 1, GET /open/v1/ads/{ad_id} returns its complete record — full media URLs, dimensions, dates, CTA, and copy:
curl -sS \
-H "X-API-Key: $ATRIA_API_KEY" \
"https://api.tryatria.com/open/v1/ads/m1234567890123456"import os
import requests
ad_id = "m1234567890123456"
resp = requests.get(
f"https://api.tryatria.com/open/v1/ads/{ad_id}",
headers={"X-API-Key": os.environ["ATRIA_API_KEY"]},
timeout=30,
)
ad = resp.json()["data"]
print(f"{ad['brand_name']} — {ad['title']}")
print(f" running since {ad['start_date']} cta: {ad['cta_type']} → {ad['link_url']}")
print(f" copy: {ad['body']!r}")
for v in ad["videos"]:
print(
f" video {v['width']}x{v['height']} ({v['duration']}s) "
f"hd: {v['url']} preview: {v['preview_image_url']}"
)const adId = "m1234567890123456";
const resp = await fetch(
`https://api.tryatria.com/open/v1/ads/${adId}`,
{ headers: { "X-API-Key": process.env.ATRIA_API_KEY } },
);
const ad = (await resp.json()).data;
console.log(`${ad.brand_name} — ${ad.title}`);
console.log(
` running since ${ad.start_date} cta: ${ad.cta_type} → ${ad.link_url}`,
);
console.log(` copy: ${JSON.stringify(ad.body)}`);
for (const v of ad.videos) {
console.log(
` video ${v.width}x${v.height} (${v.duration}s) ` +
`hd: ${v.url} preview: ${v.preview_image_url}`,
);
}The videos[0].url is the full HD source — point it at your video player or download it for offline review. For carousel ads the videos[] array may contain multiple entries; for static-image ads, check images[] instead.
Parameter notes
| Parameter | Why it matters |
|---|---|
display_format | video excludes images and carousels — long-form only makes sense for video. |
video_length | Repeatable enum bucket. Valid values: 0-15, 15-30, 30-60, 60-120, 120-. Combine 60-120 + 120- for "60 seconds and longer." |
industry | Filters on the ad's categories field — values come from the source platform's own taxonomy (e.g. electronics, shopping, health & beauty, vitamins/supplements), not a curated list. Pick a value you've actually seen in categories[] on a sample /ads response. |
sort_by | most_active ranks by how long the ad has been running. A 90-day live ad usually beats a brand-new one in signal value. |
Watch the bucket boundaries
video_lengthfilters on the ad's primary creative. An ad with both a 90s HD cut and a 30s SD cut is bucketed by the HD duration.
Going further
- Swap
sort_by=most_active→sort_by=newestand addstart_date={30 days ago}to see recent long-form launches. - Pair with the competitor research recipe to drill into a specific brand's long-form mix.
- Walk the cursor to surface the full corpus, then run your own scoring (e.g. CTA distribution, language breakdown).
