Skip to content

Send and download attachments

In the desktop or web client, use the attachment button, paste a file or image, or drop files into the message box. Review or remove the staged files, then select Send to send your text and each file as separate messages. JPEG, PNG, GIF and WebP files become images; MOV, MP4, 3GP, 3G2 and MJ2 files become videos; other formats become file attachments. The client checks the connected hub’s limits; the synthetic preview has a smaller file limit than a native hub.

Send attachments through the CLI, HTTP API or OpenClaw. The ordinary-file source limit is 512 MiB (536,870,912 bytes). Limits depend on the selected send kind:

Send kindMaximum source size
Ordinary file536,870,912 bytes
Video source52,428,800 bytes (50 MiB)
Image or voice26,214,383 bytes each (25 MiB minus 17 bytes)
StickerSending unavailable

File attachments preserve source bytes. Image sends can resize/re-encode them. See Video and image quality for outgoing preparation and how to request received copies.

CLI

  1. Send a file and allow an hour for upload, download verification and submission:

    Terminal window
    wx messages send filehelper --file ./report.pdf --wait 3600 \
    --idempotency-key report-2026-10

    --wait is in seconds; its default is 30 and attachment jobs allow up to 3,600. --detach returns the job immediately.

  2. If the wait ends, inspect the returned job:

    Terminal window
    wx jobs get JOB_ID

    While the daemon verifies the uploaded bytes, the job shows these fields:

    Phase: readback
    State: running

    Keep the job ID and key. Ending the wait leaves the daemon working.

HTTP API and SDK

  1. Inspect the connected daemon’s limits with GET /v1/accounts/{account}/capabilities. The relevant response fields are:

    {
    "mediaUploadMaxBytes": 536870912,
    "mediaSendMaxBytes": {
    "file": 536870912,
    "image": 26214383,
    "video": 52428800,
    "voice": 26214383
    }
    }

    mediaUploadMaxBytes limits staging. Check mediaSendMaxBytes[kind] before staging bytes for a particular send.

  2. Stage one file, then submit its returned id as sourceId:

    Terminal window
    curl -H "Authorization: Bearer $TOKEN" -F 'file=@report.pdf' \
    "$WX/accounts/$ACCOUNT/uploads"
    curl -X POST -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' -H 'Idempotency-Key: report-2026-10' \
    -d '{"threadId":"filehelper","kind":"file","sourceId":"SOURCE_ID"}' \
    "$WX/accounts/$ACCOUNT/sends"

    Here, WX ends in /v1. The send returns HTTP 202 with a job. Poll GET /jobs/{id}; allow up to an hour for larger files.

    The TypeScript SDK exposes the same workflow:

    const source = await client.upload(accountId, bytes, "report.pdf");
    const job = await client.sendMedia(accountId, {
    threadId: "filehelper", kind: "file", sourceId: source.id,
    standardSourceId: null, thumbnailSourceId: null,
    playSeconds: null, durationMs: null,
    }, "report-2026-10");
    const progress = await client.job(accountId, job.id);

    SDK uploads accept bytes or a Blob; Node’s openAsBlob avoids loading the source into memory. NATIVE_MAX_SOURCE_BYTES, exported by @agent-wechat/shared, is the staging ceiling.

Download files

Ordinary-file downloads also support up to 512 MiB:

Terminal window
wx messages media filehelper MESSAGE_ID --output ./saved.pdf --wait 3600

The CLI verifies size and SHA-256 before publishing the output. SDK clients can use mediaContentStream with { maxBytes: NATIVE_MAX_SOURCE_BYTES }; the default retrieval bound is 128 MiB. Check the selected asset’s size and SHA-256 when saving the stream.

OpenClaw

Set channels.agent-wechat.mediaMaxMb to allow the intended attachment size. For example, 512 permits files up to 512 MiB. The extension applies the smaller of this setting and the selected send kind’s limit before staging. Raising it cannot extend the daemon’s per-kind limits.

Ordinary audio is sent as a file; audioAsVoice selects voice. Larger ordinary files get up to an hour of job polling. If polling ends, retain the reported job ID and inspect it instead of starting another send.

Use OpenClaw’s asDocument/forceDocument option to send media as an ordinary file. Video quality options apply only to video sends.