When to use this endpoint

Use File_upload for CRM1’s sequential upload control or API clients sending a data URI. For true multipart upload, Files_upload is the simpler current route.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session and establish the tenant database context.

The handler performs no record-owner or resource-specific permission check. CRM screens may hide the action, but callers with tenant API/session access can target any matching file ID.

Parameters

ParameterTypeRequiredDescription
type_idInteger-compatibleYesLinked resource ID. Presence is checked, but zero is accepted.
type_enumInteger-compatibleEffectively yesLinked resource type; absent becomes zero. Common verified values are 0 Customer, 1 Asset Type, 2 Asset, 3 Job, 4 User, 5 recurring Job, 6 User photo, 7 report-design image, 8 Job form photo, 9 report PDF background, 10 private/non-downloadable, 11 form file, 12 Quote, and 13 email-template image. Other modules use later values; use the enum already emitted by the relevant CRM workflow.
FiledataMultipart file or data-URI stringYesMultipart field when $_FILES is populated, otherwise a data URI. The data-URI branch base64-decodes everything after the first comma without strict validation.
filenameStringData-URI branchStored display filename. Multipart upload uses the client filename.
uniqueInteger-compatibleNoTruthy makes the successful new upload the only live file for the same type/resource by deleting earlier live files through File_delete.

Example request

$result = FM_api('File_upload', [
	'type_enum' => '2',
	'type_id' => '1042',
	'filename' => 'asset-photo.jpg',
	'Filedata' => 'data:image/jpeg;base64,/9j/4AAQSkZJRg...',
]);

Example response

{
  "ok": 1,
  "id": 4821,
  "url": "files/2/1042/7d4f..."
}

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":"no file uploaded"}Multipart data exists but its Filedata request value is missing/falsy under the legacy check.
{"error":"missing or invalid parameter: type_id"}The type-ID key is absent.
{"error":"missing parameter: Filedata"}Neither multipart nor data-URI content is supplied.
{"error":"file too large. max file size is 12582912 bytes"}Decoded content exceeds the storage limit.

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

Behaviour and edge cases

  • The storage URL contains the type, resource ID, and a random MD5 token. The library stores the bytes and inserts metadata containing the uploading user ID.
  • Customer, Asset, Job, User, and recurring-Job types update parent file lists/logs inside the storage helper. Customer/Asset lists are then rebuilt again by this endpoint. Job outsourcing propagation may update the linked tenant.
  • With unique=1, previous rows remain as soft-deleted metadata with content removed and deletion-log entries. Filename/content MIME is not validated here; only byte length is enforced.

See it in Fieldmotion

CRM1

Use Upload Files on Customer, Job, Asset, User, Task, recurring-Job, Asset Type, or generic file widgets.

CRM2

Most modern drop zones use Files_upload; some shared support/client code still targets this singular route.

Related endpoints