Long-Form Video Research

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 catalog
  • GET /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

ParameterWhy it matters
display_formatvideo excludes images and carousels — long-form only makes sense for video.
video_lengthRepeatable enum bucket. Valid values: 0-15, 15-30, 30-60, 60-120, 120-. Combine 60-120 + 120- for "60 seconds and longer."
industryFilters 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_bymost_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_length filters 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_activesort_by=newest and add start_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).