Skip to main content
Follow connection setup first. You need a write-capable user key with access to the destination. This example uploads a local PDF named form.pdf.

Choose the destination

  • personal://Documents: your personal Documents folder.
  • team://Documents: your team’s Documents folder.
  • @mc/Documents: the Documents folder in an authorized scope. Also send scope: "mc:<UUID or slug>".
Send scope only for @mc destinations. For artifact:// destinations, use a storage root ID plus a relative path, not a folder ID. To upload to a chat session’s folder, send sessionId instead of targetUri. Where a file is stored and which record owns it are set separately. To attach a file to a record, set ownerType and ownerId on each file. For filings, use the filing upload example, then continue at Upload the file.

Prepare the request

Start an upload to your team’s Documents folder. Replace 12345 with the file’s size in bytes.
The response contains targetUri and files[], each with path, signedUrl, optional headers, expiresAt, and uploadToken. With onConflict: "rename", an existing file with the same name is kept and the new file gets a different name. With "fail", conflicting files are listed in conflicts[] and get no upload URL.

Upload the file

PUT the raw file bytes (not JSON or multipart) to files[0].signedUrl with exactly the headers in files[0].headers:
Don’t send your Effective API key to the storage host. Once the PUT succeeds, confirm the upload with files[0].uploadToken:
Check every results[].success, even when the status is 200. A successful result contains uri and artifact. Save artifact.id to refer to the file, and artifact.name, which can differ from the name you asked for. A failed result contains error.code and error.message. For example, NOT_FOUND means the uploaded file wasn’t found, and EXPIRED means the token expired. Don’t send scope or the owner fields again; the token already carries them.

Limits and retries

  • Each call accepts up to 100 files and a JSON body up to 1 MiB.
  • Use the signed URL before its expiresAt, and confirm within one hour.
  • Neither call is idempotent. After a lost response, check the destination before retrying; confirming twice can create a second version.
  • Search indexing runs after confirmation and isn’t finished when the call returns.
Confirming an upload doesn’t add it to a filing. To do that, continue with Add a filing item. See the initialization and completion references for full schemas.