Snapchat Ads API: set ai_content_source USER_AI_GEN on an AI video

Snap's create-media call has an optional ai_content_source field: USER_AI_GEN or SNAP_AI_GENERATED. Set it when you upload a Sume clip, then wait for READY.

5 min readSume
All posts

When you create a media entity for a Snapchat ad through the Marketing API, the body accepts an optional ai_content_source with two values, USER_AI_GEN and SNAP_AI_GENERATED. For a clip you made with Sume and uploaded yourself, USER_AI_GEN is the value that fits. Sume does not set it for you: the field lives in your call to Snap.

Snap details come from the Media page of the Marketing API, read 2026-10-02. Sume facts come from Video generation and Jobs and results. The side-by-side of disclosure fields across platforms is in our field-name comparison.

What does the create-media call look like?

The route is POST https://adsapi.snapchat.com/v1/adaccounts/{ad_account_id}/media. The body holds a media array. Each item needs name, type and ad_account_id; type is one of VIDEO, IMAGE, LENS_PACKAGE or PLAYABLE. ai_content_source is the optional extra.

Snap's page does not explain what the flag changes in the ad, what a label looks like to viewers, or whether any policy requires it. Read Snap's advertising policies for that, and do not describe it to clients as a compliance guarantee.

When do I use which value?

USER_AI_GEN marks content you generated with an AI tool, which covers a Sume render. SNAP_AI_GENERATED is for media Snap's own tools created, so it is not the value for a file that came from outside. The page lists the two names without further definitions, so the mapping here is my reading of the names; if a case is unclear, ask your Snap rep.

ai_content_source on Snap's create-media call, read 2026-10-02
ValueLikely useSet by Sume?
USER_AI_GENClip you generated elsewhere, such as a Sume renderNo, you set it
SNAP_AI_GENERATEDMedia made by Snap's own toolsNo
OmittedField is optionalNot applicable

What are the three calls?

Create the media entity, upload the file as multipart form data to POST /v1/media/{media_id}/upload, then read the media until its status goes from PENDING_UPLOAD to READY. Snap lists only those two statuses on this page. Only a READY media can be used in a creative.

Sume's job ends before this: video generation is asynchronous, so poll until completed, then download the MP4 from the content URL. Keep the Sume job id in your own record so the Snap media can be traced back to the generation that made it.

# 1) Create the media entity and say it is user-generated AI content
curl -s -X POST "https://adsapi.snapchat.com/v1/adaccounts/$AD_ACCOUNT_ID/media" \
  -H "Authorization: Bearer $SNAP_TOKEN" -H "Content-Type: application/json" \
  -d '{"media":[{"name":"Mug hook v1","type":"VIDEO",
                 "ad_account_id":"'"$AD_ACCOUNT_ID"'",
                 "ai_content_source":"USER_AI_GEN"}]}'

# 2) Download the finished Sume clip, then upload it to the new media id
curl -s -o clip.mp4 "$SUME_CLIP_URL"
curl -s -X POST "https://adsapi.snapchat.com/v1/media/$MEDIA_ID/upload" \
  -H "Authorization: Bearer $SNAP_TOKEN" -F "file=@clip.mp4"

# 3) GET /v1/media/$MEDIA_ID until the status moves PENDING_UPLOAD -> READY

How should a team keep a record?

Keep a ledger row per ad creative with the prompt, the Sume job id, the model used, the Snap media id and the ai_content_source value you sent. If someone later asks whether a creative was labeled, you can answer from the record in a minute rather than by opening ads.

Sume job ids are durable, and the docs advise storing them so work can be recovered after a process restart. Per Generation admission, queued is a normal accepted state, so your ledger should record the submit time and the completion time separately. If you re-render a clip, give the new render its own Snap media entity and its own ledger row; do not overwrite the old one.

What should I check before uploading?

Size and shape come next in the Top Snap size post. Beyond that, check the voice and the product claims in the clip, because the disclosure flag does not make an inaccurate ad acceptable.

  • Set the flag when you create the media; the page shows it only on that call.
  • Use one media entity per distinct clip so a rejected version does not block the rest.
  • Never resubmit a paid Sume request because a Snap upload failed; upload the same file again.
  • Record the Snap media id next to the Sume job id.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume