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.

4 min readSume
All posts

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.

CreatePostsRequest fields relevant to AI posts (read 2026-10-02)
FieldTypeDescription in the spec
made_with_aibooleanDisclose that the tweet contains AI-generated media
paid_partnershipbooleanDisclose a paid partnership
nullcastbooleanPost not shown in the public timeline
mediaobjectMedia 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

All Integrations posts

Written by Sume