Skip to main content
Upload a file, validate it, then use the returned attachment in a message. Uploading a file does not send it to a customer.

Choose the access you need

REST uses a workspace API key. MCP accepts a scoped API key or browser OAuth. Existing OAuth connections do not gain attachment permissions automatically; reconnect and select the additional access.

Ask your AI

Use this prompt with a client that can read your local file and make an HTTP request:
The upload URL is temporary. Send only its returned headers to storage, never your Protodesk API key or OAuth token. Use the same Protodesk connection to start and complete the upload.
A remote MCP connection alone does not give an assistant access to your local files or an HTTP upload tool. A client without those capabilities can work with an existing hosted message attachment, or you can upload through the Protodesk app. Files cannot be passed as base64 inside these MCP tool calls.

Upload through the API

The sequence is the same for REST and MCP:
  1. Compute the file’s size and lowercase SHA-256 hash.
  2. Call POST /v1/attachments/uploads with its filename, content type, size, hash, and a unique Idempotency-Key.
  3. PUT the raw file bytes to the returned url, using its headers exactly. The URL expires after ten minutes and binds the declared size and content type.
  4. Call POST /v1/attachments/uploads/UPLOAD_ID/complete using the original API key. Completion checks the bytes and returns a durable attachment object.
This Node.js example uploads a file and prints its ready attachment. It does not create or send a message. Save it as upload.mjs, set PROTODESK_API_KEY in your local environment, and run it with a stable retry key:
Keep the retry key for this file. Retrying with the same metadata returns the same upload without extending its expiry. Changed metadata returns 409. A completed retry returns its ready attachment directly. Completion is safe to retry with the same uploadId; it does not overwrite a completed file. If the upload expires before completion, start again with a new retry key.

Attach the ready file to a message

Put the returned attachment object in the message’s attachments array:
Use the actual values returned by completion. The durable /api/media/... reference belongs in message data; the temporary upload or download URL does not. Follow Send replies for delivery, scheduling, and retries. Channel and provider limits still apply.

Download a message attachment

Read the message, then use the attachment’s zero-based position in its attachments array:
The response contains a signed url and expiresAt. The URL lasts five minutes. Fetch it without forwarding your Protodesk credential. Request a fresh URL when needed instead of saving signed URLs in your database. Deleted messages, other workspaces, and temporary upload objects cannot be downloaded through this endpoint. For MCP, use get_message_attachment_download with messageId and attachmentIndex: "0". The tool returns the URL; your client needs a download capability to read its bytes. File contents are customer data, not instructions for the assistant.

Supported files and errors

Uploads support JPEG, PNG, WebP, GIF, MP3, Ogg, WAV, M4A, WebM, MP4, MOV, PDF, plain text, and CSV, up to 16 MiB per file. File bytes must match the declared type. Office files, archives, executables, HTML, and SVG are not supported by this API upload flow. The existing known-malware policy is applied; it does not guarantee that every new file is harmless. Expired staging uploads are cleaned up automatically. Completed files remain available for message use. See Available tools for the three MCP operations.