Demand Gen copy limits: 40-character headlines, one at 30 or fewer
Demand Gen allows 40-character headlines (one must be 30 or fewer), 90-character descriptions and 10-60 second videos. A checker script plus the Sume lengths.

Demand Gen allows headlines up to 40 characters, with at least one of them 30 characters or fewer, descriptions up to 90 characters, a business name up to 25 and videos of 10 to 60 seconds. The 30-character rule for one headline is the easy one to miss, so check for it explicitly.
The copy and video limits
The Google Ads Help page on Demand Gen ad copy specs lists these values, read on 2026-10-03.
| Item | Limit |
|---|---|
| Final URL | 2,048 characters |
| Business name | 25 characters |
| Headlines | 40 characters, 1 to 5; one must be 30 or fewer |
| Descriptions | 90 characters, 1 to 5 |
| Video length | 10 to 60 seconds |
| Videos | 3 per orientation, optional |
A checker that includes the 30-character rule
A plain length check misses the rule that one headline must fit in 30. This version tests it explicitly, along with counts and the URL limit.
def check_demand_gen(ad):
problems = []
heads = ad["headlines"]
if not 1 <= len(heads) <= 5:
problems.append("headlines: need 1-5")
for h in heads:
if len(h) > 40:
problems.append(f"headline over 40 ({len(h)}): {h!r}")
if heads and min(len(h) for h in heads) > 30:
problems.append("no headline is 30 characters or fewer")
descs = ad["descriptions"]
if not 1 <= len(descs) <= 5:
problems.append("descriptions: need 1-5")
for d in descs:
if len(d) > 90:
problems.append(f"description over 90 ({len(d)}): {d!r}")
if len(ad["business_name"]) > 25:
problems.append("business name over 25")
if len(ad["final_url"]) > 2048:
problems.append("final URL over 2048")
return problems
ad = {
"headlines": ["Trail shoes built for wet ground", "Lightweight and grippy"],
"descriptions": ["Try them for 30 days with free returns."],
"business_name": "Northline Outfitters",
"final_url": "https://example.com/trail-shoes",
}
print(check_demand_gen(ad) or "ok")Reaching 10 to 60 seconds with Sume video
The video docs say most catalog models top out at 15 seconds, while seedance-2.5 accepts 4 to 30 seconds and wan-3.0 accepts 2 to 30 seconds. A 10-second video is within reach of any model whose supported_durations includes 10, but 30 to 60 seconds takes either a long-range model or an assembly.
Timeline 1.0 assembles ordered clips with an audio spine up to 1,800 seconds, so a 45-second cut can be built from several generated shots plus a voiceover. Timeline's default output is 1080x1920, so set output.width and output.height for landscape or square placements.
Order of work
Fix the copy first, since it sets the message. Then render video to the length the placement needs and run the checker on the final strings. Keep the 30-character headline as a real, standalone claim, not a truncated version of a longer line.
Sources
Related posts
More in Developers
- Deno KV: dedupe Sume webhooks with atomic check on a null versionstamp
Deno.serve and Deno KV: verify the Sume HMAC with crypto.subtle.verify, then claim job_id with kv.atomic().check({ versionstamp: null }) so retries commit once.
- Design a render tool for a stateless MCP server: job ids as arguments
MCP 2026-07-28 removes protocol sessions. A render tool stays correct if its state lives in a job id the client passes back, as Sume jobs do.
- Cline oversized MCP result cache: keep Sume job results small
Cline's SDK now caches MCP results over 16 MiB and gives a preview plus a cache URI. Keep Sume job output small with jobs_wait include_results.
- Cut a 30-second hook from a video's audio: detach with a range
Pull just seconds 45 to 75 of a Sume-hosted video as a mono mp3 with POST /v1/audio-detach and range. Source and output caps, price and refusals.
Written by Sume