File storage and sharing API with virus scanning
Store files per tenant with virus scanning, folders, trash and expiring share links, all through an API.
What it does
- The File Storage and Sharing API gives your app a place to put files without running object storage yourself. Upload a file, get an id back, then list, search, move, star, trash, restore or delete it. Files sit in S3-compatible object storage, and their details sit in a database so search is quick.
- It solves the "we just need to keep a PDF" problem that turns into a month of work: virus checks, folders, access logs, signed download links and sharing rules. Here those parts already exist, and they are scoped to your tenant.
- Uploads are scanned with ClamAV before storage, and each file gets a status such as "clean". Hashes (MD5 and SHA256) are returned so you can check integrity. Files are private by default, with an optional public flag, an optional unique key for duplicate detection, tags and a description. For large files, a streaming upload endpoint takes the body directly.
- Sharing comes in two kinds. Share with one specific user, or mint a link with an unguessable token. Links can expire and can have a download limit. Permissions are view, download or edit. The owner can list and revoke shares, and the "shared with me" list shows what others have given you. Every access is logged with the caller's IP address and user agent.
- Deleting is gentle: soft-delete moves a file to the trash, restore brings it back, and a hard delete removes it. Folders, a starred list, a search endpoint and a stats summary round out the set.
- Send an X-API-Key header or a Bearer token from Takelan SSO. Over the limit you get a 429 with a Retry-After header. The size cap is a deployment setting, with a default of 100 MB per file in the current build, so ask the capabilities endpoint of the document API or check your environment instead of assuming.
- Affordable by design. Start free* inside platform limits. *Free within platform limits; usage beyond limits may be charged to maintain the platform. Connected ShadowCradle organizations can switch on Takelan SSO and these free* services with one switch. Airgap licences work without any Takelan connection.
See how it works
From upload to a stored, checked file
Sharing with a link or a user
Example use cases
Customer uploads in your app
A portal lets clients attach contracts and screenshots. The app uploads through the API, stores the returned file id with the ticket, and every file has been virus-checked.
Send a large report without email attachments
An MSP creates a share link that expires in 48 hours with a download limit of one, and puts the link in the email instead of a 40 MB attachment.
Internal documents with a trash can
A small team keeps policy documents in folders. Someone deletes the wrong one, and the trash list brings it back with one call.
Audit who opened a file
After a customer asks "who downloaded this?", the access log answers with time, IP address and user agent for each access.
Large files straight from a script
A backup script streams a large export through the stream endpoint instead of building a multipart form in memory, within your deployment's size cap.
Back a data store with files
The Data Warehouse can reference a file you uploaded as a document body, so big payloads stay in object storage while their metadata stays searchable.
Try it
Upload a file
curl -X POST https://app.takelan.com/api/v1/files/upload \
-H "X-API-Key: $TAKELAN_API_KEY" \
-F "file=@contract.pdf" \
-F "description=Signed contract" \
-F "tags=legal,2026" \
-F "is_public=false"
# Response (abridged, fictional)
# {
# "file_id": "123e4567-e89b-12d3-a456-426614174000",
# "filename": "contract.pdf",
# "file_size": 482113,
# "content_type": "application/pdf",
# "is_public": false,
# "virus_scan_status": "clean"
# }Create a public link that expires
curl -X POST https://app.takelan.com/api/v1/files/123e4567-e89b-12d3-a456-426614174000/share \
-H "X-API-Key: $TAKELAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "permission": "download", "expires_in_hours": 48, "download_limit": 1 }'
# Response (abridged, fictional)
# { "id": "77aa...c3", "permission": "download", "is_active": true,
# "expires_at": "2026-11-01T10:00:00Z", "download_limit": 1, "access_count": 0 }Leave out "shared_with_user_id" to make a link. Include it to share with one Takelan user instead.
Endpoints
POST /api/v1/files/uploadUpload a file (multipart). Virus-scanned, hashed, private by default.POST /api/v1/files/upload/streamStreaming upload for large files.GET /api/v1/files/listList your files.GET /api/v1/files/searchSearch files.GET /api/v1/files/starred/listList starred files.GET /api/v1/files/trash/listList files in the trash.GET /api/v1/files/{file_id}/infoFile details.GET /api/v1/files/{file_id_or_key}/signed-urlGet a time-limited download URL.GET /api/v1/files/{file_id_or_key}Download a file.PUT /api/v1/files/{file_id}Update file details.PATCH /api/v1/files/{file_id}/moveMove a file to a folder.PATCH /api/v1/files/{file_id}/starStar or unstar.PATCH /api/v1/files/{file_id}/soft-deleteMove to the trash.PATCH /api/v1/files/{file_id}/restoreRestore from the trash.DELETE /api/v1/files/{file_id}Delete permanently.GET /api/v1/files/stats/summaryStorage statistics.POST /api/v1/files/foldersCreate a folder.GET /api/v1/files/foldersList folders.PUT /api/v1/files/folders/{folder_id}Rename or move a folder.DELETE /api/v1/files/folders/{folder_id}Delete a folder.POST /api/v1/files/{file_id}/shareShare with a user or create a public link (permission view, download or edit).GET /api/v1/files/{file_id}/sharesList shares on a file.GET /api/v1/files/shared/listList shares you created.GET /api/v1/files/shared-with-meFiles others shared with you.DELETE /api/v1/files/share/{token_or_id}Revoke a share.GET /api/v1/files/public/{share_token}Open a public share link.
MCP
Available as tools through /mcp/utils. Listing, searching and reading file details work with a read-only key. Uploads, shares, moves and deletes are writes, so they are off by default and need the tenant's writes switch plus a key that is not read-only. File contents (blob downloads) are not exposed as tools, and routes that return share tokens are marked sensitive. About MCP
Common questions
how to upload a file with an API and scan it for viruses
POST the file as multipart form data to /api/v1/files/upload with your X-API-Key. It is scanned with ClamAV before storage, and the response includes a virus_scan_status and file hashes.
how do I create an expiring download link for a file
Call POST /api/v1/files/{file_id}/share without a user id. You get a link with an unguessable token. Set expires_in_hours and an optional download_limit, and pick view, download or edit permission.
what is the maximum file upload size
The cap is a deployment setting, with a default of 100 MB per file in the current build. Use the streaming upload endpoint for large bodies, and check your environment for its actual value.
can I recover a deleted file through the API
Yes. Soft-delete moves a file to the trash, and the restore endpoint brings it back. Only the hard delete is permanent.
who can see my uploaded files
Files are private to the uploader by default and are tied to your tenant. A file is readable by others only if you set it public or share it. Every access is logged with IP address and user agent.
is it S3 compatible storage
Files are kept in S3-compatible object storage behind the API. You talk to the Takelan API, not to the bucket, so you get scanning, sharing and logging with no storage setup.
how do I authenticate to the file storage API
Send X-API-Key with a key from your tenant, or a Bearer token from Takelan SSO. Read-only keys are refused on write methods. Over the limit you get a 429 with Retry-After.
is file storage free to try
It is affordable by design: start free* within platform limits. *Free within platform limits; usage beyond limits may be charged to maintain the platform.
