Skip to content

Contracts and limits

The rules that apply to every method: how requests and results pair up, how failures surface, and the limits you have to design around.

Bulk-first. Every method takes List<...Request> and returns a parallel-index List<...Result>. Single-item callers pass a one-element list and read index [0].

Per-item outcomes. Each result carries success, errorCode, errorMessage. A failing item does not abort the rest of the list. Branch on errorCode, not on errorMessage text.

Call-level exception. FilesApiException is thrown only for whole-call failures: missing custom permission, null/empty request list, unknown Callable action, malformed Callable args. In Flow, this maps to the fault path.

Opaque fileId. A ContentDocumentId for Salesforce-stored files, the storage object key otherwise. Pass it back verbatim; do not parse it. One id works across all providers and all methods.

Callouts. uploadFiles, requestUploadUrls, getDownloadUrls (external), and getFileBodies (external) perform HTTP callouts: max 100 per transaction, cannot run after DML in the same transaction, cannot run directly in triggers (use a Queueable). listFiles, renameFiles, relocateFiles (accept), and getStorageReadiness are callout-free. deleteFiles performs a callout on a last-attachment delete (the strict external byte-delete), and moveFiles performs callouts on SharePoint, where the physical file moves too.

ConstantMeaning
ERROR_ACCESS_DENIEDMissing custom permission, or no access to the record/file
ERROR_NOT_FOUNDFile or record does not exist / is not visible
ERROR_INVALID_INPUTRequired field missing or malformed
ERROR_UNSUPPORTED_PROVIDEROperation unavailable on the active provider
ERROR_FILE_TOO_LARGEExceeds the ~4MB Apex byte-relay cap
ERROR_STREAMING_NOT_ENABLEDrelocateFiles: large-file streaming not entitled for the org
ERROR_RELOCATION_PENDINGA relocate handle was used as a fileId before its async copy finished
ERROR_PROVIDER_FAILEDDownstream storage/database failure (cause in the message)
ERROR_EXTERNAL_DELETE_FAILEDdeleteFiles: the external byte-delete failed, or the file belongs to a non-active provider, so nothing changed in Salesforce
LimitValue
Base64 upload / file-body read~4MB binary per file (Apex heap + provider cap)
listFilesactive provider only (opt out with includeAllProviders), max 200 files per record, createdDate DESC
Download URLs (external)presigned, expire within minutes - fetch just before use
confirmUploadsidempotent per uploadKey (replay returns the existing file)
relocateFilesasync, no size ceiling (multipart); accept is callout-free; idempotent per (source file, record)