When to use this endpoint

Use this only when a legacy caller has a stored path, not a file ID. For integrations needing the original filename and bytes together, prefer File_getFile.

Authentication and permissions

Normal requests authenticate with signed API-key fields or a logged-in CRM session. This handler explicitly requires login; CRM2 Files View is not an additional requirement here.

UserFile routes are outside the dispatcher’s File/Files TeamAccess object mapping. They require login where implemented and enforce the tenant rules described here, but do not call File_readGuard or apply the CRM2 Files View check. Do not treat a successful path read as proof of a file-record visibility decision.

Parameters

ParameterTypeRequiredDescription
fileTenant-relative stored pathYes for explicit RPC requestsTrimmed path such as files/0/1042/ or user-photos/37.jpg. One leading slash is removed before storage access. This is neither a numeric file ID nor an external HTTP URL. Literal .. anywhere or private/ anywhere is rejected; checks are case-sensitive.
returnInteger-compatibleNoDefault/zero streams bytes and exits. Any nonzero integer returns {mimetype,base64}; unlike File_getFile, this flag enables useful JSON and no filename is included.
job_idInteger-compatible Job IDNoUsed only by missing-image recovery. It is not a file ID, file owner filter or normal-path prerequisite. Supply a real related Job when recovering its app photo.
Path URL / t segmentLegacy browser routeNoWhen file is absent, the handler may derive a path/tenant from the request URI. A derived /t= segment is removed and sets one-year public cache headers. An explicit file parameter does not use that URI cache branch. Query-string ?t=... is a different cache-busting pattern.

Example request

$image = FM_api('UserFile_get', ['file'=>'user-photos/37.jpg','return'=>'1']);

Example response

{
  "mimetype": "image/jpeg",
  "base64": "/9j/4AAQSkZJRg..."
}

Default success is raw bytes with download headers, not JSON. In return mode the exact keys are mimetype and base64; there is no filename, id, filesize or ok wrapper. Empty/falsy stored content is treated as missing.

MIME type is derived from the live stored filename matching the path, falling back to the path. Supported browser types include JPEG/PNG/GIF/WebP/SVG/PDF; unknown extensions are application/octet-stream. HTML is downloaded as an attachment; SVG receives a restrictive content-security policy.

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error": "missing or invalid parameter: file"}No explicit/derived file path is available; return mode without file rejects before login.
{"error": "no hacking, please"}The requested path contains .. or private/.
{"error": "this file belongs to another company account."}A positive URI-derived tenant differs from the authenticated tenant. Zero/current tenant resolves to the authenticated tenant.
{"error": "file does not exist"}No bytes are found and no more specific image-recovery result applies.
{"error": "image requested for re-upload from app"}A missing own-user image caused a recovery command; this is not a completed image download.
{"error": "could not lock file download; please retry"}The per-tenant/per-user lock cannot be opened or acquired within five seconds.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • A positive URI tenant cannot switch the authenticated account. The normal path reads the current tenant; image recovery can consult a verified active outsourcing link or the supplied Job’s saved outsourcing metadata.
  • For a missing images/x... path, legacy recovery can read/copy an outsourcee’s image, use a related outsourced Job copy, or queue an image reupload command for the app user. An error can therefore accompany a side effect; repeating it is not a pure read.
  • Reads do not call File_readGuard or validate the file’s CRM2 Files View permission. Path-based tenant protection is different from ID-based per-file visibility. Do not use this route to test whether a file ID is authorized.
  • There is no pagination or range/chunked transfer support in the handler. Bytes are loaded into memory and return mode adds base64 overhead. The cache branch emits headers but does not implement If-None-Match/304 handling itself.
  • Download work is serialized by a per-tenant/per-user file lock with a five-second acquisition deadline and a shutdown release. This differs from the sibling getFile handler.

Side effects

  • The storage library can update access/size metadata, hydrate bytes or restore archives. Missing-image recovery may copy/register image bytes, update app commands and stamp a User so the app downloads the command. Both handlers also attempt legacy /tmp path cleanup after success; they do not intentionally delete the stored backend object.

See it in Fieldmotion

CRM1

CRM1 User profiles, Asset/Job photos and report-design images construct /f//... links. The current direct JavaScript callers do not name this RPC explicitly; ordinary file tables generally use File_get.

CRM2

CRM2 User profiles, photos, Job forms, maps and report designers construct /f//... image links. Current imageSetUrl also uses File_getByUrl with base64=1. A path-link consumer is not proof that this exact RPC was called; inspect the actual request.

Related endpoints