From 89bb4bcd0d1c353006d999767825ce1d5434f20d Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Fri, 19 Jun 2026 13:07:01 -0500 Subject: [PATCH 1/2] docs(connectors): document POST /api/connectors/files (image upload) Adds the OpenAPI contract for the new connectors file-upload endpoint that stages an image into Composio storage and returns a { name, mimetype, s3key } descriptor for use in file_uploadable action fields (e.g. LINKEDIN_CREATE_LINKED_IN_POST.images[]). - social.json: new POST /api/connectors/files path (apiKey/bearer auth, 200/400/401/502) + UploadConnectorFileRequest / UploadConnectorFileResponse schemas, mirroring the execute-action contract. Additive diff. - upload-file.mdx reference page + docs.json nav entry. Contract for recoupable/chat#1809. Co-Authored-By: Claude Opus 4.8 (1M context) --- api-reference/connectors/upload-file.mdx | 4 + api-reference/openapi/social.json | 110 +++++++++++++++++++++++ docs.json | 1 + 3 files changed, 115 insertions(+) create mode 100644 api-reference/connectors/upload-file.mdx diff --git a/api-reference/connectors/upload-file.mdx b/api-reference/connectors/upload-file.mdx new file mode 100644 index 0000000..88a48ef --- /dev/null +++ b/api-reference/connectors/upload-file.mdx @@ -0,0 +1,4 @@ +--- +title: 'Upload Connector File' +openapi: "/api-reference/openapi/social.json POST /api/connectors/files" +--- diff --git a/api-reference/openapi/social.json b/api-reference/openapi/social.json index bd543f8..788c082 100644 --- a/api-reference/openapi/social.json +++ b/api-reference/openapi/social.json @@ -895,6 +895,72 @@ } } } + }, + "/api/connectors/files": { + "post": { + "security": [ + { + "apiKeyAuth": [] + }, + { + "bearerAuth": [] + } + ], + "description": "Stage an image into Composio file storage so it can be attached to a connector action that accepts a file_uploadable field (e.g. LINKEDIN_CREATE_LINKED_IN_POST.images[], TWITTER_CREATION_OF_A_POST). Provide a publicly reachable image `url` and the `toolSlug` of the action you intend to post with; the image is fetched server-side, uploaded to Composio storage (deduplicated by content hash), and the returned `{ name, mimetype, s3key }` descriptor is passed straight into that action's file_uploadable array on POST /api/connectors/actions.", + "requestBody": { + "description": "The image URL to stage and the action it will be attached to.", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadConnectorFileRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Image staged. Returns the Composio file descriptor to embed in the action's file_uploadable array.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadConnectorFileResponse" + } + } + } + }, + "400": { + "description": "Bad request — missing or invalid `url` (must be a reachable URL) or `toolSlug`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Unauthorized — invalid or missing API key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "502": { + "description": "Upstream failure staging the file into Composio storage (the image fetch failed or Composio errored).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } } }, "components": { @@ -2309,6 +2375,50 @@ "description": "ISO 8601 timestamp of when the action was executed server-side." } } + }, + "UploadConnectorFileRequest": { + "type": "object", + "required": [ + "url", + "toolSlug" + ], + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Publicly reachable URL of the image to stage. Fetched server-side and uploaded to Composio storage. Required." + }, + "toolSlug": { + "type": "string", + "description": "The action slug the image will be attached to, UPPERCASE_SNAKE_CASE (e.g. `LINKEDIN_CREATE_LINKED_IN_POST`). Scopes the upload to that tool/toolkit. Required." + } + } + }, + "UploadConnectorFileResponse": { + "type": "object", + "required": [ + "success", + "name", + "mimetype", + "s3key" + ], + "properties": { + "success": { + "type": "boolean" + }, + "name": { + "type": "string", + "description": "Stored filename." + }, + "mimetype": { + "type": "string", + "description": "Detected MIME type of the stored file." + }, + "s3key": { + "type": "string", + "description": "Composio storage key. Pass this together with `name` and `mimetype` in the action's file_uploadable array, e.g. `parameters.images[]` for LINKEDIN_CREATE_LINKED_IN_POST." + } + } } } } diff --git a/docs.json b/docs.json index 2658430..719ac1e 100644 --- a/docs.json +++ b/docs.json @@ -394,6 +394,7 @@ "api-reference/connectors/authorize", "api-reference/connectors/disconnect", "api-reference/connectors/list-actions", + "api-reference/connectors/upload-file", "api-reference/connectors/execute-action" ] } From f862885124ac41efb9081dda55f768b74e005fcf Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Sat, 20 Jun 2026 15:15:28 -0500 Subject: [PATCH 2/2] =?UTF-8?q?docs(connectors):=20address=20review=20?= =?UTF-8?q?=E2=80=94=20drop=20vendor=20name,=20KISS,=20add=20cross-links?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace third-party vendor name (Composio) with 'Connector' in all /api/connectors/files descriptions. - Simplify descriptions (KISS): drop action-slug examples and the long staging explanation from the path + s3key descriptions. - Add a bidirectional hyperlink between Upload Connector File and Execute Connector Action for easier dev reference. Co-Authored-By: Claude Opus 4.8 (1M context) --- api-reference/openapi/social.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api-reference/openapi/social.json b/api-reference/openapi/social.json index 788c082..2588e4e 100644 --- a/api-reference/openapi/social.json +++ b/api-reference/openapi/social.json @@ -810,7 +810,7 @@ }, "post": { "security": [{ "apiKeyAuth": [] }, { "bearerAuth": [] }], - "description": "Execute a connector action with the given parameters. The `actionSlug` must come from a prior call to GET /api/connectors/actions, and `parameters` must match the `parameters` JSON Schema returned for that action. The action's parent connector must be currently connected (`isConnected: true` in the catalog) — otherwise this endpoint returns 409. The `result` field passes through whatever the underlying connector returns; its shape is action-specific.", + "description": "Execute a connector action with the given parameters. The `actionSlug` must come from a prior call to GET /api/connectors/actions, and `parameters` must match the `parameters` JSON Schema returned for that action. The action's parent connector must be currently connected (`isConnected: true` in the catalog) — otherwise this endpoint returns 409. The `result` field passes through whatever the underlying connector returns; its shape is action-specific. To attach an image to a `file_uploadable` parameter (e.g. `images`), first stage it with [Upload Connector File](/api-reference/connectors/upload-file) and pass the returned descriptor.", "requestBody": { "description": "Action to execute and the parameters for it", "required": true, @@ -906,7 +906,7 @@ "bearerAuth": [] } ], - "description": "Stage an image into Composio file storage so it can be attached to a connector action that accepts a file_uploadable field (e.g. LINKEDIN_CREATE_LINKED_IN_POST.images[], TWITTER_CREATION_OF_A_POST). Provide a publicly reachable image `url` and the `toolSlug` of the action you intend to post with; the image is fetched server-side, uploaded to Composio storage (deduplicated by content hash), and the returned `{ name, mimetype, s3key }` descriptor is passed straight into that action's file_uploadable array on POST /api/connectors/actions.", + "description": "Stage an image into Connector file storage so it can be attached to a connector action that accepts a file_uploadable field. The returned descriptor is embedded in a file_uploadable array on [Execute Connector Action](/api-reference/connectors/execute-action).", "requestBody": { "description": "The image URL to stage and the action it will be attached to.", "required": true, @@ -920,7 +920,7 @@ }, "responses": { "200": { - "description": "Image staged. Returns the Composio file descriptor to embed in the action's file_uploadable array.", + "description": "Image staged. Returns the Connector file descriptor to embed in the action's file_uploadable array.", "content": { "application/json": { "schema": { @@ -950,7 +950,7 @@ } }, "502": { - "description": "Upstream failure staging the file into Composio storage (the image fetch failed or Composio errored).", + "description": "Upstream failure staging the file into Connector storage (the image fetch failed or Connector errored).", "content": { "application/json": { "schema": { @@ -2386,7 +2386,7 @@ "url": { "type": "string", "format": "uri", - "description": "Publicly reachable URL of the image to stage. Fetched server-side and uploaded to Composio storage. Required." + "description": "Publicly reachable URL of the image to stage. Fetched server-side and uploaded to Connector storage. Required." }, "toolSlug": { "type": "string", @@ -2416,7 +2416,7 @@ }, "s3key": { "type": "string", - "description": "Composio storage key. Pass this together with `name` and `mimetype` in the action's file_uploadable array, e.g. `parameters.images[]` for LINKEDIN_CREATE_LINKED_IN_POST." + "description": "Connector storage key. Pass this together with `name` and `mimetype` in the action's file_uploadable array." } } }