Stored path files
Download a stored path
/a/UserFile_get
Retrieve a tenant-relative stored path as a download or MIME/base64 JSON.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
file | Tenant-relative stored path | Yes for explicit RPC requests | Trimmed path such as files/0/1042/ |
return | Integer-compatible | No | Default/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_id | Integer-compatible Job ID | No | Used 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 segment | Legacy browser route | No | When file is absent, the handler may derive a path/tenant from the request URI. A derived /t= |
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
| Response | Condition |
|---|---|
{"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/
CRM2
CRM2 User profiles, photos, Job forms, maps and report designers construct /f/
Related endpoints
- File identifiers and downloads compares the path/ID/URL contracts.
File_getFilereturns the original filename and base64 bytes by file ID.