← back

FILEDITCH API

Two endpoints, no auth, no keys

FileDitch has two public APIs. Upload lives on new.fileditch.com: POST a file, get a JSON response with a URL. Status lives on fileditchfiles.st: give it a file link, learn whether that file still exists and how big it is. No API keys, no accounts, no bullshit. Both are free to use from scripts, bots, monitors and browsers.

On this page
Upload API   Filename rules   Responses & errors   Limits Status API   Response & tri-state   Examples (curl, JS, Python)   Caching, CORS & rate limits

Upload API — new.fileditch.com

Files are kept as long as storage allows — no scheduled expiry. See retention under Limits below.

Endpoint
POST / PUThttps://new.fileditch.com/upload.php
Raw body upload — fastest method
curl -T yourfile.mp4 "https://new.fileditch.com/upload.php?filename=yourfile.mp4"
Raw POST with --data-binary
curl -X POST \
  -H "Content-Type: application/octet-stream" \
  --data-binary @yourfile.mp4 \
  "https://new.fileditch.com/upload.php?filename=yourfile.mp4"
Multipart — also works
curl -F "file=@yourfile.mp4" https://new.fileditch.com/upload.php
Python
import requests
with open("yourfile.mp4", "rb") as f:
    r = requests.put("https://new.fileditch.com/upload.php",
                     params={"filename": "yourfile.mp4"}, data=f)
print(r.json()["url"])
JavaScript (browser or Node 18+)
const res = await fetch("https://new.fileditch.com/upload.php?filename=" + encodeURIComponent(file.name), {
  method: "PUT",
  body: file            // a File / Blob / Buffer / ReadableStream
});
const { url } = await res.json();

Filename

The server resolves the filename in this order. The first match wins:

1.  ?filename=  query parameter
2.  X-Filename  request header
3.  Content-Disposition header  (filename="..." or RFC 5987 filename*=)
4.  Multipart field filename
5.  Random hex string           (fallback)

Unicode filenames are preserved. Spaces become underscores; the characters / \ : * ? " < > | # & ; = % + @ ! , ` ~ ^ $ { } become underscores too; leading/trailing dots are removed; only the last path component is used. Names longer than 255 bytes are replaced by a random name.

Success response

successboolean — always true on success
urlstring — direct link to the uploaded file. The part after the domain is the file path you feed to the Status API
filenamestring — final filename stored on server
sizeinteger — file size in bytes
Example
{
  "success": true,
  "url": "https://fileditchfiles.st/alpha27/a3f9c1b2d4e5f6071829/yourfile.mp4",
  "filename": "yourfile.mp4",
  "size": 104857600
}

Error response

{ "error": "description" }
400Empty file, no file sent, or incomplete upload (connection closed early)
403Blocked file type (executables, scripts, web files)
405Wrong HTTP method
411Multipart upload without Content-Length (chunked transfer-encoding) — use a raw PUT instead
413File exceeds 150 GB limit
429Rate limited — back off and retry (see the Retry-After header)
500Server error
503Server busy — retry in a few seconds
507Server out of space — try again later

Limits

Max file size150 GB
RetentionIndefinite while accessed — only files untouched for 45+ days may be removed, and only when space is needed
Blocked extensionsphp, html, js, exe, apk, sh, py, bat and other executables & scripts — the file content is sniffed too, so renaming an executable does not help
Rate limits2 requests/s and 10 concurrent uploads per IP on this endpoint
Upload durationNo limit for raw uploads (curl -T / --data-binary). Multipart (curl -F) requests are cut off after 6 hours — use a raw upload for very large files
AuthenticationNone required

Status API — fileditchfiles.st

A tiny read-only endpoint that answers one question: does this file still exist, and how big is it? Use it to check links before you post them, to prune dead links from a bot or a forum, to monitor an upload you care about, or to show a file size without downloading anything. It is deliberately open: no proof-of-work, no landing page, no user-agent checks, so curl, Python, cron jobs and browsers are all welcome.

Endpoint
GET / HEADhttps://fileditchfiles.st/api/<folder>/<random-id>/<filename>

The path is exactly the part after the domain in a normal FileDitch link. Take any file URL and insert /api after the host and you have the status URL. This is the only supported form; do not call any .php file directly. fileditchfiles.me works identically. Percent-encode filenames with spaces or non-ASCII characters as you would in any URL; a literal + in a name stays a +.

File link → status link
https://fileditchfiles.st/charlie21/aa59bb5b707fb30f002e/cat.mp4
https://fileditchfiles.st/api/charlie21/aa59bb5b707fb30f002e/cat.mp4

Response

Always application/json, always HTTP 200 when the request itself is valid. Three fields, nothing else:

filestring — the normalised path that was checked, always starting with /
statustrue — the file exists on its origin
false — the file is gone (deleted, expired, or never existed)
"unknown" — the origin could not be reached right now. Not a verdict; retry later
sizeinteger bytes when status is true, otherwise null
Exists
{"file":"/charlie21/aa59bb5b707fb30f002e/cat.mp4","status":true,"size":50720388}
Gone
{"file":"/charlie21/aa59bb5b707fb30f002e/cat.mp4","status":false,"size":null}
Origin unreachable
{"file":"/charlie21/aa59bb5b707fb30f002e/cat.mp4","status":"unknown","size":null}

Treat the three states differently. false is final and safe to act on (drop the link). "unknown" is transient: a shard was slow or restarting. Do not delete anything on "unknown"; check again in a minute. In JavaScript remember that "unknown" is a truthy string, so test with === true, not a bare if (status).

Errors

Only a bad request gets a non-200. The body is then {"error":"..."} with one of these codes:

400bad-path — path missing, not starting with /, or containing . / .. segments
405method-not-allowed — only GET, HEAD and OPTIONS are accepted
429Rate limited — slow down (see limits below)
503api-disabled — the API is switched off for maintenance. Honour the Retry-After header

Examples

curl
curl -s https://fileditchfiles.st/api/charlie21/aa59bb5b707fb30f002e/cat.mp4

# just the status, with jq
curl -s https://fileditchfiles.st/api/charlie21/aa59bb5b707fb30f002e/cat.mp4 | jq .status

# HEAD works too if you only want the headers
curl -sI https://fileditchfiles.st/api/charlie21/aa59bb5b707fb30f002e/cat.mp4
Shell one-liner: turn any file URL into a status check
fdstat() { curl -s "$(echo "$1" | sed -E 's#^(https?://[^/]+)/#\1/api/#')"; }
fdstat https://fileditchfiles.st/charlie21/aa59bb5b707fb30f002e/cat.mp4
JavaScript (browser, CORS is open)
async function fileditchStatus(fileUrl) {
  const u = new URL(fileUrl);
  const r = await fetch(`${u.origin}/api${u.pathname}`);
  if (!r.ok) throw new Error(`status api ${r.status}`);
  return r.json();                 // { file, status, size }
}

const s = await fileditchStatus("https://fileditchfiles.st/charlie21/aa59bb5b707fb30f002e/cat.mp4");
if (s.status === true)        console.log("alive,", s.size, "bytes");
else if (s.status === false)  console.log("gone");
else                          console.log("unknown, retry later");
Python
import requests
from urllib.parse import urlsplit

def fileditch_status(file_url):
    u = urlsplit(file_url)
    r = requests.get(f"{u.scheme}://{u.netloc}/api{u.path}", timeout=15)
    r.raise_for_status()
    return r.json()

s = fileditch_status("https://fileditchfiles.st/charlie21/aa59bb5b707fb30f002e/cat.mp4")
if s["status"] is True:
    print("alive", s["size"], "bytes")
elif s["status"] is False:
    print("gone")
else:
    print("unknown, retry later")
Upload, then verify
URL=$(curl -sT cat.mp4 "https://new.fileditch.com/upload.php?filename=cat.mp4" | jq -r .url)
curl -s "${URL/fileditchfiles.st\//fileditchfiles.st/api/}"

Caching, CORS & rate limits

CachingAnswers are cached server-side for 1 hour, and the response carries Cache-Control: public, max-age=3600 so browsers and proxies may cache it too. A false (gone) answer is re-checked after 60 seconds, so a freshly uploaded file that briefly reads as gone while it propagates will flip to true quickly. A file that is deleted can therefore still read as true for up to an hour
CORSAccess-Control-Allow-Origin: * — call it straight from any web page. OPTIONS preflight is answered with 204
Rate limits20 requests/s per IP with a burst of 40, and 40 concurrent connections. Above that you get 429. Spread bulk checks out; with the cache, re-checking the same file more than once an hour is pointless anyway
MethodsGET, HEAD, OPTIONS. Anything else returns 405 with an Allow header
User agentsAny. The bot filtering on the normal file pages does not apply to /api/
Side effectsNone. A status check is not counted as a download and does not touch the 45-day retention clock
AuthenticationNone required

Something missing that you need? Tell us on the contact page or Discord.