Storage API integration quickstart
Use REST V2 for new storage integrations where an equivalent exists. The REST reference also covers V1 capabilities that do not have V2 equivalents, including restore, version history, ZIPs, and thumbnails.
Authentication and request format
Base URL: https://api.files.fm. V2 actions use POST form fields, not a JSON request body. Use user and user_access_token from a dedicated integration account. File uploads use multipart form data. MCP Bearer and DVS JSON examples are separate contracts.
Create, upload, list, and download
# Examples contain placeholders. These commands create and upload data.
curl --fail-with-body --silent --show-error --max-time 30 \
'https://api.files.fm/api_v2/create_folder' \
--data-urlencode 'user=YOUR_USER' \
--data-urlencode 'user_access_token=YOUR_API_TOKEN' \
--data-urlencode 'folder_name=Integration test' --data-urlencode 'access_type=PRIVATE'
Retain the returned folder_hash and capability keys. Hashes and keys are opaque strings. A private folder is an appropriate default for business data.
curl --fail-with-body --silent --show-error --max-time 120 \
'https://api.files.fm/api_v2/upload_file' \
-F 'user=YOUR_USER' -F 'user_access_token=YOUR_API_TOKEN' \
-F 'folder_hash=RETURNED_FOLDER_HASH' -F '[email protected]'
Retain the returned file_hash. Upload one file per request; account limits apply. List with get_folder_content using the folder hash and form auth. The result is an array, not a DVS items/total envelope. This V2 listing has no documented pagination parameters; do not invent page or limit support.
curl --fail-with-body --silent --show-error --max-time 30 \
'https://api.files.fm/api_v2/download_file' \
--data-urlencode 'user=YOUR_USER' --data-urlencode 'user_access_token=YOUR_API_TOKEN' \
--data-urlencode 'file_hash=RETURNED_FILE_HASH' --output downloaded-file.txt
Download returns raw file bytes. Verify the HTTP result before treating the output as a successful file.
JavaScript on a trusted server
async function storage(action, params) {
const body = new URLSearchParams({ ...params, user: process.env.FILESFM_USER,
user_access_token: process.env.FILESFM_API_TOKEN });
const response = await fetch(`https://api.files.fm/api_v2/${action}`, {
method: 'POST', body, signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`Storage HTTP ${response.status}`);
return response.json();
}
// Creates a private folder; run only when authorized.
const folder = await storage('create_folder', { folder_name: 'Integration test', access_type: 'PRIVATE' });
const items = await storage('get_folder_content', { folder_hash: folder.folder_hash });
For multipart upload use FormData with file as a Blob and do not manually set its Content-Type boundary. Use response.arrayBuffer() for download instead of .json().
PHP 7.4+
<?php
$params = ['user' => getenv('FILESFM_USER'), 'user_access_token' => getenv('FILESFM_API_TOKEN'),
'folder_hash' => getenv('FILESFM_FOLDER_HASH')];
$curl = curl_init('https://api.files.fm/api_v2/get_folder_content');
curl_setopt_array($curl, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query($params), CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30]);
$body = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($body === false || $status !== 200) { throw new RuntimeException('Storage request failed: ' . $status); }
$items = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
Errors, limits, and retries
V2 failures may have an empty body despite the JSON Content-Type. Some permission and not-found conditions use 405, not 403/404. Check the endpoint's documented statuses; legacy scripts can return plain text or endpoint-specific error objects.
No universal REST quota is published. Anonymous V1 folder listing is separately throttled and delayed; authenticated V2 listing does not inherit that anonymous interface. Observe actual 429 and retry guidance. Retry reads with bounded backoff; reconcile create/upload outcomes before retrying writes. No general idempotency-key contract is documented.