curl --request POST \
--url https://{your-subdomain}.neetoengage.com/api/external/v2/attachments \
--header 'Accept: <accept>' \
--header 'Content-Type: multipart/form-data' \
--header 'X-Api-Key: <x-api-key>' \
--form file=@example-fileconst form = new FormData();
form.append('file', '<string>');
const options = {method: 'POST', headers: {'X-Api-Key': '<x-api-key>', Accept: '<accept>'}};
options.body = form;
fetch('https://{your-subdomain}.neetoengage.com/api/external/v2/attachments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{your-subdomain}.neetoengage.com/api/external/v2/attachments"
files = { "file": ("example-file", open("example-file", "rb")) }
headers = {
"X-Api-Key": "<x-api-key>",
"Accept": "<accept>"
}
response = requests.post(url, files=files, headers=headers)
print(response.text){
"id": "40f7e262-7adb-4940-b84a-e770264211d9",
"filename": "cover.png",
"content_type": "image/png",
"byte_size": 482133,
"checksum": "1B2M2Y8AsgTpgAmY7PhCfg==",
"key": "j5ysfeyrkbwhh980krdqpk81ksfj",
"metadata": {
"organization_id": "6f9f4b00-68d4-45fb-be8e-1839bf7d70ac",
"identified": true
},
"created_at": "2026-10-13T04:28:54.272Z",
"attachable_sgid": "eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL25lZXRv...",
"signed_id": "eyJfcmFpbHMiOnsiZGF0YSI6IjQwZjdlMjYyLTdh...",
"blob_url": "https://spinkart.neetoengage.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMi.../cover.png"
}{
"error": "Could not authenticate, invalid API Key"
}{
"error": "File is required"
}Upload an attachment
Uploads a file to the workspace and returns its signed_id. Pass the signed_id to the CreateChangelog MCP tool as cover_image_signed_id to use the file as a changelog’s cover image. Only the workspace that uploaded the file can use it. Files can be up to 50 MB. This endpoint is under /api/external/v2, not /api/external/v1.
curl --request POST \
--url https://{your-subdomain}.neetoengage.com/api/external/v2/attachments \
--header 'Accept: <accept>' \
--header 'Content-Type: multipart/form-data' \
--header 'X-Api-Key: <x-api-key>' \
--form file=@example-fileconst form = new FormData();
form.append('file', '<string>');
const options = {method: 'POST', headers: {'X-Api-Key': '<x-api-key>', Accept: '<accept>'}};
options.body = form;
fetch('https://{your-subdomain}.neetoengage.com/api/external/v2/attachments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{your-subdomain}.neetoengage.com/api/external/v2/attachments"
files = { "file": ("example-file", open("example-file", "rb")) }
headers = {
"X-Api-Key": "<x-api-key>",
"Accept": "<accept>"
}
response = requests.post(url, files=files, headers=headers)
print(response.text){
"id": "40f7e262-7adb-4940-b84a-e770264211d9",
"filename": "cover.png",
"content_type": "image/png",
"byte_size": 482133,
"checksum": "1B2M2Y8AsgTpgAmY7PhCfg==",
"key": "j5ysfeyrkbwhh980krdqpk81ksfj",
"metadata": {
"organization_id": "6f9f4b00-68d4-45fb-be8e-1839bf7d70ac",
"identified": true
},
"created_at": "2026-10-13T04:28:54.272Z",
"attachable_sgid": "eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL25lZXRv...",
"signed_id": "eyJfcmFpbHMiOnsiZGF0YSI6IjQwZjdlMjYyLTdh...",
"blob_url": "https://spinkart.neetoengage.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMi.../cover.png"
}{
"error": "Could not authenticate, invalid API Key"
}{
"error": "File is required"
}{your-subdomain} with your workspace’s subdomain. Learn how to find your subdomain in Workspace subdomain.
Headers
API key. Refer to Authentication for more information.
Must be application/json.
application/json Body
The file to upload.
Response
The uploaded file.
Unique identifier of the uploaded file.
Name of the uploaded file.
Media type of the file, such as image/png.
Size of the file in bytes.
Base64 MD5 checksum of the file.
Storage key of the file.
Storage service that holds the file.
Metadata of the file, including the workspace it belongs to.
When the file was uploaded.
Signed global ID of the file.
Signed reference to the file. Pass it as cover_image_signed_id to the CreateChangelog MCP tool.
URL that redirects to the file.