Upload a file and get a permanent direct link back. Every response is JSON and you do not need an API key.
https://anyafilehost.vercel.appThree endpoints cover most needs: upload a file, import one from a link, and open it again from its direct URL.
Cached delivery with support for range requests.
Files are encrypted before they reach storage.
Plain JSON and nothing to configure.
/upload/hosturl?url={media_url}/{timestamp}.{ext}/uploadSend the file as multipart/form-data. Vercel limits one request body to about 4.5 MB, so use this for small files. For anything bigger, see Large files.
| Name | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The file to upload. |
curl -X POST https://anyafilehost.vercel.app/upload \
-F "file=@path/to/file.jpg"/hosturl?url={media_url}We download the remote file on our server and store it for you. It works for files up to the 100 MB limit, which makes it handy for copying images that already live somewhere else.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Yes | A public http or https link to the file. Remember to URL-encode it. |
curl "https://anyafilehost.vercel.app/hosturl?url=https://example.com/image.jpg"The website cuts each file into pieces of at most 4,000,000 bytes, uploads every piece, and then asks the server to save the result. You can do the same from your own code, for files up to 100 MB.
/api/upload/chunkThe body is the raw bytes of one piece. Send x-upload-id (random, 8 to 64 characters, the same for every piece), x-chunk-index (0, 1, 2 and so on) and x-file-name (URL-encoded). You get back a signed record for that piece.
/api/upload/completeSend JSON with { uploadId, name, type, meta?, chunks }, where chunks are the records from the step above. meta can hold width, height and duration. The response is the normal success JSON.
const CHUNK = 4_000_000;
const uploadId = crypto.randomUUID().replaceAll('-', '');
const chunks = [];
for (let i = 0; i * CHUNK < file.size; i++) {
const res = await fetch('https://anyafilehost.vercel.app/api/upload/chunk', {
method: 'POST',
headers: {
'x-upload-id': uploadId,
'x-chunk-index': String(i),
'x-file-name': encodeURIComponent(file.name),
},
body: file.slice(i * CHUNK, (i + 1) * CHUNK),
});
chunks.push(await res.json());
}
const done = await fetch('https://anyafilehost.vercel.app/api/upload/complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uploadId, name: file.name, type: file.type, chunks }),
});
console.log((await done.json()).url);/{timestamp}.{ext}Every upload returns a direct link such as https://anyafilehost.vercel.app/1753020712833.png. Open it in a browser, put it in an <img> tag, or hot-link it anywhere. The file is decrypted as it is sent, and range requests work, so video and audio can seek. Types that can run code in a browser (html, js, css, xml and svg) always download.
{
"data": "https://anyafilehost.vercel.app/1753020712833.png",
"url": "https://anyafilehost.vercel.app/1753020712833.png",
"id": "1753020712833.png",
"filename": "sample.png",
"size": 83638,
"uploaded_on": "2025-07-20T14:11:52.833Z",
"media_type": "image/png"
}data and urlidfilenamesizeuploaded_onmedia_type{
"error": "Failed to download file from URL"
}Every file is split into pieces and each piece is encrypted on our server before it is sent to Telegram. The pieces are saved with random names, so the people who can see the Telegram chat only find unreadable data.
When someone opens your link, the pieces are fetched, checked and decrypted on the fly. If a piece was changed in storage, the download stops instead of serving damaged data. Files uploaded before encryption was added keep working as they are.
The admin dashboard has its own sign in page at /admin. For scripts, the same routes also accept HTTP Basic credentials built from the USERNAME and PASSWORD environment variables.
/admin Needs sign inBrowse, preview, copy and delete everything that has been uploaded.
/admin/api/media?page=1&limit=100 Needs sign in/delete-images Needs sign incurl -X POST https://anyafilehost.vercel.app/delete-images \
-u admin:YOUR_PASSWORD \
-H "Content-Type: application/json" \
-d '["https://anyafilehost.vercel.app/1753020712833.png"]'POST /upload for small files and /hosturl for files that already exist online.ENABLE_AUTH, uploads need the admin credentials too.