X API made_with_ai: disclose AI media when you create a post
The X API v2 create-post body has a made_with_ai boolean to disclose AI-generated media. Where it sits, what it needs, and how to prep the clip with Sume first.

Yes: the X API v2 create-post request body includes a boolean field named made_with_ai, described in the OpenAPI specification as disclosing that the post contains AI-generated media. Set it to true on the request that attaches your generated video or image. It sits next to paid_partnership, a separate disclosure field, and neither field is a substitute for the other.
Where is made_with_ai in the request?
In the X OpenAPI document (version 2.169 when read), CreatePostsRequest lists made_with_ai and paid_partnership as booleans alongside nullcast, text and the media object. The description reads: disclose that the tweet contains AI-generated media. The field is a flag on the post, not on the uploaded media, so you set it when you create the post and not when you upload.
| Field | Type | Description in the spec |
|---|---|---|
| made_with_ai | boolean | Disclose that the tweet contains AI-generated media |
| paid_partnership | boolean | Disclose a paid partnership |
| nullcast | boolean | Post not shown in the public timeline |
| media | object | Media attachments; media_ids holds 1-4 ids |
What should the flow look like?
Prepare the asset, upload it through X's media endpoints to get a media id, then create the post with media.media_ids and made_with_ai: true. A text-only post has nothing to disclose, so leave the flag off unless the attached media is AI-made.
On the Sume side, a generated clip may need a cut before upload. Sume's video-trim returns a new MP4 artifact with duration_seconds, which you download and upload to X. Remember that Sume's trim only reads Sume-hosted video, so import external footage first with POST /v1/media-imports.
import json, os, urllib.request
body = {
"video_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4",
"start": 0,
"duration": 30,
"precision": "exact"
}
req = urllib.request.Request(
"https://api.sume.com/v1/video-trim",
data=json.dumps(body).encode(),
headers={
"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "x-clip-001",
},
method="POST",
)
print(urllib.request.urlopen(req).read().decode())What does the flag not do?
The spec describes a disclosure flag and nothing more. It does not say what X shows to viewers, whether it is required in a given region, or whether it interacts with X's own policies, so read X's policy pages for those questions. A flag that is wrong in either direction is your risk, since you are the one setting it.
What should I confirm before shipping?
Check the live OpenAPI document again at release time, because the spec number changes often. The video trim guide explains the Sume side.
Sources
Related posts
More in Integrations
- X media upload total_bytes ceiling of 16 GiB: trim long AI video first
X's media upload init accepts total_bytes up to 17179869184 (16 GiB). Why the cap rarely binds for AI clips, and how Sume video-trim keeps uploads short.
- YouTube channelBanners.insert: 6 MB JPEG or PNG limit for AI banners
YouTube's channelBanners.insert accepts a JPEG or PNG up to 6 MB (6291456 bytes). Generate a banner with Sume Images and keep the file under the cap.
- YouTube Data API containsSyntheticMedia: set it on videos.insert
YouTube Data API v3 VideoStatus has containsSyntheticMedia, a boolean for altered or synthetic media. Where to set it and how to trim a Sume clip first.
- YouTube playlistImages API: 50 MB cover images from an AI image
YouTube's playlistImages insert and update accept a JPEG or PNG up to 50 MB (52428800 bytes). Make a cover with Sume Images; the spec gives no pixel size.
Written by Sume