POST /mcp/material/upload
Raw file bytes in, storageId and a public url out. Send the file’s path in X-Selda-Path, which is how Selda maps material to a company. Then hand the ids to material.import, or to drafts.attach / runs.attach for a file that goes out WITH a message. For an image the url is also what a picture placed in the body needs.
| REST | POST /v1/material/upload |
| RPC form | POST /mcp/material/upload with "fn": "POST /mcp/material/upload" |
| Scope | pipeline |
| Sandbox key | allowed |
| Extra entitlement | none |
| MCP tools | selda_upload_material, selda_upload_file |
| Internal function | convex/mcpApi.ts (httpAction) |
A free sandbox key may call it.
Arguments
This endpoint takes the raw bytes of one file as the request body, not a JSON args object.
| Header | Required | What it is |
|---|---|---|
Authorization | yes | Bearer sk_live_... or Bearer sk_test_... |
X-Selda-Path | yes | The file’s path inside your folder. That path is how Selda maps a file to a company. |
Example request
curl -X POST https://api.selda.ai/v1/material/upload \
-H "Authorization: Bearer sk_live_..." \
-H "X-Selda-Path: boreo/filterit/analysis.pdf" \
-H "Content-Type: application/pdf" \
--data-binary @analysis.pdfExample response
{
"value": { "storageId": "<storageId>", "path": "boreo/filterit/analysis.pdf", "sizeBytes": 20481 },
"request_id": "req_..."
}Generated from convex/lib/mcpRegistry.ts. Nothing in this reference sends: launchRun is in no
registry and never will be, so a script can prepare a campaign completely and a person still
presses send in the app.