From ba4b702df9762c2e476dcb65a2a0aacc770b156c Mon Sep 17 00:00:00 2001 From: Taylor Caldwell Date: Wed, 5 Feb 2025 14:50:29 -0800 Subject: [PATCH 1/2] Add media metadata endpoints to spec --- mint.json | 19 +- openapi.json | 792 +++++++++++++++++++------ x-api/media/media-metadata-create.mdx | 3 + x-api/media/media-subtitles-create.mdx | 3 + x-api/media/media-subtitles-delete.mdx | 3 + 5 files changed, 646 insertions(+), 174 deletions(-) create mode 100644 x-api/media/media-metadata-create.mdx create mode 100644 x-api/media/media-subtitles-create.mdx create mode 100644 x-api/media/media-subtitles-delete.mdx diff --git a/mint.json b/mint.json index d6d4ed7cc..cb82c0587 100644 --- a/mint.json +++ b/mint.json @@ -866,18 +866,23 @@ ] }, { - "group": "Media Upload", + "group": "Media", "pages": [ "x-api/media/introduction", { - "group": "Guides", + "group": "Upload", "pages": [ - "x-api/media/quickstart/best-practices", - "x-api/media/quickstart/media-upload-chunked" + { + "group": "Guides", + "pages": [ + "x-api/media/quickstart/best-practices", + "x-api/media/quickstart/media-upload-chunked" + ] + }, + "x-api/media/media-upload", + "x-api/media/media-upload-status" ] - }, - "x-api/media/media-upload", - "x-api/media/media-upload-status" + } ] }, { diff --git a/openapi.json b/openapi.json index 95a5a30d7..377a45632 100644 --- a/openapi.json +++ b/openapi.json @@ -2710,217 +2710,397 @@ } } }, - "/2/media/upload": { - "get": { - "security": [ - { - "OAuth2UserToken": [ - "media.write" - ] - } - ], - "tags": [ - "MediaUpload" - ], - "summary": "Media Upload Status", - "description": "Get MediaUpload Status", - "externalDocs": { - "url": "https://developer.x.com" - }, - "operationId": "uploadMediaStatus", - "parameters": [ - { - "name": "media_id", - "in": "query", - "description": "Media id for the requested media upload status.", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "style": "form" - }, - { - "name": "command", - "in": "query", - "description": "The command for the media upload request.", - "required": true, - "schema": { - "type": "string", - "enum": [ - "STATUS" + "/2/media/metadata/create": { + "post": { + "security": [ + { + "OAuth2UserToken": [ + "media.write" ] }, - "style": "form" - } - ], - "responses": { - "200": { - "description": "The request has succeeded.", + { + "UserToken": [] + } + ], + "tags": [ + "MediaUpload" + ], + "summary": "Metadata Create", + "description": "MetadataCreate", + "externalDocs": { + "url": "https://developer.x.com" + }, + "operationId": "metadataCreate", + "parameters": [], + "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MediaUploadStatusResponse" + "$ref": "#/components/schemas/MetadataCreateRequest" } } } }, - "default": { - "description": "The request has failed.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" + "responses": { + "200": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MetadataCreateResponse" + } } - }, - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/Problem" + } + }, + "default": { + "description": "The request has failed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } } } } } } - }, - "post": { - "security": [ - { - "OAuth2UserToken": [ - "media.write" - ] - } - ], - "tags": [ - "MediaUpload" - ], - "summary": "Media Upload", - "description": "MediaUpload", - "externalDocs": { - "url": "https://developer.x.com" - }, - "operationId": "uploadMedia", - "parameters": [ - { - "name": "total_bytes", - "in": "query", - "description": "Total number of bytes being uploaded.", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - }, - "style": "form" - }, - { - "name": "media_type", - "in": "query", - "description": "The MIME type of the media being uploaded. For example, video/mp4.", - "required": true, - "schema": { - "type": "string" - }, - "style": "form" - }, - { - "name": "media_category", - "in": "query", - "description": "A string enum value which identifies a media usecase. This identifier is used to enforce usecase specific constraints (e.g. file size, video duration) and enable advanced features.", - "required": false, - "schema": { - "type": "string", - "enum": [ - "amplify_video", - "tweet_gif", - "tweet_image", - "tweet_video", - "dm_video", - "dm_image", - "subtitles" + }, + "/2/media/subtitles/create": { + "post": { + "security": [ + { + "OAuth2UserToken": [ + "media.write" ] }, - "style": "form" + { + "UserToken": [] + } + ], + "tags": [ + "MediaUpload" + ], + "summary": "Subtitle Create", + "description": "SubtitleCreate", + "externalDocs": { + "url": "https://developer.x.com" }, - { - "name": "additional_owners", - "in": "query", - "description": "A comma-separated list of user IDs to set as additional owners allowed to use the returned media_id in Tweets or Cards. Up to 100 additional owners may be specified.", - "required": false, - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UserId" + "operationId": "subtitleCreate", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubtitlesCreateRequest" + } } - }, - "style": "form" + } }, - { - "name": "command", - "in": "query", - "description": "The type of command to use.", - "required": true, - "schema": { - "type": "string", - "enum": [ - "INIT", - "FINALIZE", - "APPEND" - ] + "responses": { + "200": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubtitlesCreateResponse" + } + } + } }, - "style": "form" - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "$ref": "#/components/schemas/MediaUploadAppendRequest" + "default": { + "description": "The request has failed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } } } } - }, - "responses": { - "200": { - "description": "The request has succeeded.", + } + }, + "/2/media/subtitles/delete": { + "post": { + "security": [ + { + "OAuth2UserToken": [ + "media.write" + ] + }, + { + "UserToken": [] + } + ], + "tags": [ + "MediaUpload" + ], + "summary": "Subtitle Delete", + "description": "SubtitleDelete", + "externalDocs": { + "url": "https://developer.x.com" + }, + "operationId": "subtitleDelete", + "parameters": [], + "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MediaUploadStatusResponse" + "$ref": "#/components/schemas/SubtitlesDeleteRequest" } } } }, - "202": { - "description": "The request has succeeded.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MediaUploadInitResponse" + "responses": { + "200": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubtitlesDeleteResponse" + } + } + } + }, + "default": { + "description": "The request has failed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } } } } + } + } + }, + "/2/media/upload": { + "get": { + "security": [ + { + "OAuth2UserToken": [ + "media.write" + ] + } + ], + "tags": [ + "MediaUpload" + ], + "summary": "Media Upload Status", + "description": "Get MediaUpload Status", + "externalDocs": { + "url": "https://developer.x.com" }, - "204": { - "description": "The request has succeeded.", - "content": {} + "operationId": "uploadMediaStatus", + "parameters": [ + { + "name": "media_id", + "in": "query", + "description": "Media id for the requested media upload status.", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "style": "form" + }, + { + "name": "command", + "in": "query", + "description": "The command for the media upload request.", + "required": true, + "schema": { + "type": "string", + "enum": [ + "STATUS" + ] + }, + "style": "form" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaUploadStatusResponse" + } + } + } + }, + "default": { + "description": "The request has failed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } + } + } + } + } + }, + "post": { + "security": [ + { + "OAuth2UserToken": [ + "media.write" + ] + } + ], + "tags": [ + "MediaUpload" + ], + "summary": "Media Upload", + "description": "MediaUpload", + "externalDocs": { + "url": "https://developer.x.com" }, - "default": { - "description": "The request has failed.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" + "operationId": "uploadMedia", + "parameters": [ + { + "name": "total_bytes", + "in": "query", + "description": "Total number of bytes being uploaded.", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "style": "form" + }, + { + "name": "media_type", + "in": "query", + "description": "The MIME type of the media being uploaded. For example, video/mp4.", + "required": true, + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "name": "media_category", + "in": "query", + "description": "A string enum value which identifies a media usecase. This identifier is used to enforce usecase specific constraints (e.g. file size, video duration) and enable advanced features.", + "required": false, + "schema": { + "type": "string", + "enum": [ + "amplify_video", + "tweet_gif", + "tweet_image", + "tweet_video", + "dm_video", + "dm_image", + "subtitles" + ] + }, + "style": "form" + }, + { + "name": "additional_owners", + "in": "query", + "description": "A comma-separated list of user IDs to set as additional owners allowed to use the returned media_id in Tweets or Cards. Up to 100 additional owners may be specified.", + "required": false, + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserId" } }, - "application/problem+json": { + "style": "form" + }, + { + "name": "command", + "in": "query", + "description": "The type of command to use.", + "required": true, + "schema": { + "type": "string", + "enum": [ + "INIT", + "FINALIZE", + "APPEND" + ] + }, + "style": "form" + } + ], + "requestBody": { + "content": { + "multipart/form-data": { "schema": { - "$ref": "#/components/schemas/Problem" + "$ref": "#/components/schemas/MediaUploadAppendRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaUploadStatusResponse" + } + } + } + }, + "202": { + "description": "The request has succeeded.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaUploadInitResponse" + } + } + } + }, + "204": { + "description": "The request has succeeded.", + "content": {} + }, + "default": { + "description": "The request has failed.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + }, + "application/problem+json": { + "schema": { + "$ref": "#/components/schemas/Problem" + } } } } } } - } - }, + }, "/2/notes": { "get": { "security": [ @@ -10539,6 +10719,26 @@ "$ref": "#/components/schemas/AppRulesCount" } }, + "AllowDownloadStatus": { + "type": "object", + "properties": { + "allow_download": { + "type": "boolean", + "example": "true" + } + } + }, + "AltText": { + "type": "object", + "properties": { + "text": { + "type": "string", + "description": "Alternate text Metadata (Must be <=1000 chars)", + "pattern": "^.{0,1000}$", + "example": "dancing cat" + } + } + }, "AnimatedGif": { "allOf": [ { @@ -11757,6 +11957,19 @@ } } }, + "FoundMediaOrigin": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "external_id" + }, + "provider": { + "type": "string", + "example": "giphy" + } + } + }, "FullTextEntities": { "type": "object", "properties": { @@ -14307,6 +14520,44 @@ } } }, + "MetadataCreateRequest": { + "type": "object", + "required": [ + "media_id" + ], + "properties": { + "allow_download_status": { + "$ref": "#/components/schemas/AllowDownloadStatus" + }, + "alt_text": { + "$ref": "#/components/schemas/AltText" + }, + "found_media_origin": { + "$ref": "#/components/schemas/FoundMediaOrigin" + }, + "media_id": { + "$ref": "#/components/schemas/MediaId" + }, + "sticker_info": { + "$ref": "#/components/schemas/StickerInfo" + }, + "upload_source": { + "$ref": "#/components/schemas/UploadSource" + } + } + }, + "MetadataCreateResponse": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, "MuteUserMutationResponse": { "type": "object", "properties": { @@ -15255,6 +15506,61 @@ "description": "The start time of the bucket.", "format": "date-time" }, + "Sticker": { + "type": "object", + "properties": { + "aspect_ratio": { + "type": "number", + "format": "double" + }, + "group_annotation_id": { + "type": "number", + "format": "long" + }, + "id": { + "type": "string" + }, + "sticker_set_annotation_id": { + "type": "number", + "format": "long" + }, + "transform_a": { + "type": "number", + "format": "double" + }, + "transform_b": { + "type": "number", + "format": "double" + }, + "transform_c": { + "type": "number", + "format": "double" + }, + "transform_d": { + "type": "number", + "format": "double" + }, + "transform_tx": { + "type": "number", + "format": "double" + }, + "transform_ty": { + "type": "number", + "format": "double" + } + } + }, + "StickerInfo": { + "type": "object", + "properties": { + "stickers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sticker" + } + } + } + }, "StreamingLikeResponseV2": { "type": "object", "properties": { @@ -15291,6 +15597,149 @@ } } }, + "SubtitleDeleteInfo": { + "type": "object", + "properties": { + "subtitles": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "language_code": { + "type": "string", + "description": "The language code should be a BCP47 code (e.g. 'en\", \"sp\")", + "pattern": "^[a-z]{2}$" + } + } + } + } + } + }, + "SubtitleInfo": { + "type": "object", + "properties": { + "subtitles": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Subtitles" + } + } + } + }, + "Subtitles": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "description": "Language name in a human redable form" + }, + "language_code": { + "type": "string", + "description": "The language code should be a BCP47 code (e.g. 'en\", \"sp\")", + "pattern": "^[a-z]{2}$" + }, + "media_id": { + "$ref": "#/components/schemas/MediaId" + } + } + }, + "SubtitlesCreateRequest": { + "type": "object", + "properties": { + "media_category": { + "$ref": "#/components/schemas/MediaCategory" + }, + "media_id": { + "$ref": "#/components/schemas/MediaId" + }, + "subtitle_info": { + "$ref": "#/components/schemas/SubtitleInfo" + } + } + }, + "SubtitlesCreateResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "associated_subtitles": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Subtitles" + } + }, + "id": { + "$ref": "#/components/schemas/MediaId" + }, + "media_category": { + "$ref": "#/components/schemas/MediaCategory" + } + } + }, + "errors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, + "SubtitlesDeleteRequest": { + "type": "object", + "properties": { + "media_category": { + "$ref": "#/components/schemas/MediaCategory" + }, + "media_id": { + "$ref": "#/components/schemas/MediaId" + }, + "subtitle_info": { + "$ref": "#/components/schemas/SubtitleDeleteInfo" + } + } + }, + "SubtitlesDeleteResponse": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "deleted_subtitles": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "language_code": { + "type": "string", + "description": "The language code should be a BCP47 code (e.g. 'en\", \"sp\")", + "pattern": "^[a-z]{2}$" + } + } + } + }, + "id": { + "$ref": "#/components/schemas/MediaId" + }, + "media_category": { + "$ref": "#/components/schemas/MediaCategory" + } + } + }, + "errors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/Problem" + } + } + } + }, "Topic": { "type": "object", "description": "The topic of a Space, as selected by its creator.", @@ -16334,6 +16783,15 @@ "format": "date-time", "example": "2021-01-06T18:40:40.000Z" }, + "UploadSource": { + "type": "object", + "properties": { + "text": { + "type": "string", + "description": "Upload Source" + } + } + }, "UploadUrl": { "type": "string", "description": "URL to which the user will upload their Tweet or user IDs.", diff --git a/x-api/media/media-metadata-create.mdx b/x-api/media/media-metadata-create.mdx new file mode 100644 index 000000000..7c4713723 --- /dev/null +++ b/x-api/media/media-metadata-create.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /2/media/metadata/create +--- \ No newline at end of file diff --git a/x-api/media/media-subtitles-create.mdx b/x-api/media/media-subtitles-create.mdx new file mode 100644 index 000000000..380e9876a --- /dev/null +++ b/x-api/media/media-subtitles-create.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /2/media/subtitles/create +--- \ No newline at end of file diff --git a/x-api/media/media-subtitles-delete.mdx b/x-api/media/media-subtitles-delete.mdx new file mode 100644 index 000000000..3b79511e4 --- /dev/null +++ b/x-api/media/media-subtitles-delete.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /2/media/subtitles/delete +--- \ No newline at end of file From 68309a48d1405625a8daa7ad123e4a4409485371 Mon Sep 17 00:00:00 2001 From: Taylor Caldwell Date: Thu, 6 Feb 2025 16:23:53 -0800 Subject: [PATCH 2/2] Add media metadata and subtitles endpoint reference --- mint.json | 8 ++++++++ openapi.json | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/mint.json b/mint.json index cb82c0587..0875100a9 100644 --- a/mint.json +++ b/mint.json @@ -882,6 +882,14 @@ "x-api/media/media-upload", "x-api/media/media-upload-status" ] + }, + { + "group": "Metadata", + "pages": [ + "x-api/media/media-metadata-create", + "x-api/media/media-subtitles-create", + "x-api/media/media-subtitles-delete" + ] } ] }, diff --git a/openapi.json b/openapi.json index 377a45632..614fa99b5 100644 --- a/openapi.json +++ b/openapi.json @@ -14389,6 +14389,17 @@ } } }, + "MediaCategory": { + "type": "string", + "description": "The media category of uploaded media", + "enum": [ + "amplify_video", + "tweet_gif", + "tweet_image", + "tweet_video", + "subtitles" + ] + }, "MediaHeight": { "type": "integer", "description": "The height of the media in pixels.",