How file fields appear
An action’sinput exposes files in one of two shapes:
- A URL field — e.g. Instagram’s
image_url. Pass a URL string directly. - A file-uploadable object — e.g. Google Drive’s
file_to_uploador LinkedIn’simages[]. Pass an object:{ "name", "mimetype", "s3key" }.
GET /api/actions/{integration_id}/{action_id}
to see which fields an action has.
The easy path: a public URL
For either shape, hand ClawLink a public HTTPS URL and it does the rest — fetches the bytes server-side and uploads them to the provider. No client-side file handling needed, which makes this the right approach for raw HTTP, MCP, Hermes, and CLI callers.URL rules
- Must be publicly reachable and serve the raw file bytes — not an HTML page, and not behind a login.
- Share links are handled for you. Google Drive (
drive.google.com) and Dropbox links are automatically rewritten to direct-download form. Query-string / signed URLs and most CDNs work as-is. - Private/LAN addresses are rejected (
localhost,127.0.0.1,10.x,192.168.x, etc.) — the server can’t reach them. - If a URL returns HTML instead of bytes, ClawLink makes one attempt to resolve a social
preview image (
og:image/twitter:image) before failing withmedia_url_not_a_file.
The file-uploadable shape
When a field is a file-uploadable object, itss3key is flexible:
string
required
Filename, e.g.
"photo.jpg".string
required
MIME type, e.g.
"image/jpeg", "application/pdf".string
required
One of: a public HTTPS URL (re-hosted for you, above); an Apollo key returned by
a prior ClawLink upload (passed through unchanged); or, only when using the OpenClaw
npm plugin, a local file path under an OpenClaw media directory.
If you accidentally send the reference under
url or path instead of s3key, the
relay still recovers it — but s3key is the documented field.Uploading local bytes over raw HTTP
If your file is on your own machine (not a public URL), use the base64files
envelope on the tool endpoint, POST /api/tools/{tool_name}/execute. This is the only
way to send raw bytes directly.
How it links up: set the file-uploadable field’s s3key to any placeholder string, then
add a files[] entry whose pointer equals that same string. ClawLink matches
files[].pointer === arguments.<field>.s3key, uploads the bytes, and rewrites the key
before calling the provider.
files[] entry requires all five string fields: pointer, name, mimetype,
md5 (hex MD5 of the decoded bytes), and dataBase64.
Limits
Agent-runtime upload (curl ingest)
When an agent (OpenClaw ClawHub plugin, CLI, MCP, Hermes) calls a tool with a local path it can’t read, the action fails withmissing_file_bytes and the error hint
contains a ready-to-run curl line pointing at POST /api/files/ingest. The agent’s
shell runs it to upload the bytes and gets back an Apollo s3key to retry with.
This endpoint is authenticated by a short-lived, single-use HMAC token that ClawLink mints
inside that error hint — you don’t call it cold. As a direct HTTP caller, prefer a
public URL or the base64 files envelope above.
Local-file upload requires the server-side
FILE_INGEST_SECRET to be configured. If it
isn’t, /api/files/ingest returns 503 and only the URL / base64 paths are available.