1. Get a key
Sign in at /login, then visit /dashboard/api-keys and click Generate key. The token is shown once — copy it immediately and store it in your CI / scripts. We keep only a SHA-256 hash on our side, so a lost token can only be revoked, not recovered.
Tokens look like fxf_ followed by 64 hex characters. Use them in an Authorization header with the Bearer scheme.
Temporary upload tokens
For browser / third-party uploads, mint a short-lived token from your backend so the client never sees your key:
curl -X POST https://upload.fixitfy.com.tr/api/v1/upload-token \
-H "Authorization: Bearer fxf_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": 3600}'
{ "ok": true, "token": "ut_eyJ1Ijoi…", "expires_at": "2026-06-01T13:00:00.000Z" }The client then uploads with Authorization: Bearer ut_… exactly like a key, until it expires (60 s – 7 days). These tokens are stateless and signed — they can't be revoked individually, so keep the TTL short.
2. Endpoint
POST https://upload.fixitfy.com.tr/api/v1/upload
- Content type:
multipart/form-data - Form field:
file(the image bytes — PNG, JPG, GIF, WebP, or AVIF up to 20 MB) - Header:
Authorization: Bearer fxf_xxxxxxxxxxxxxxxxxxxxxxxx…
3. cURL example
curl -X POST https://upload.fixitfy.com.tr/api/v1/upload \ -H "Authorization: Bearer fxf_YOUR_KEY_HERE" \ -F "file=@/path/to/image.png"
4. Success response
HTTP/1.1 200 OK
Content-Type: application/json
{
"ok": true,
"filename": "FIXITFY-aB3xZ7nQrL9p.png",
"url": "https://upload.fixitfy.com.tr/images/FIXITFY-aB3xZ7nQrL9p.png",
"delete_url": "https://upload.fixitfy.com.tr/api/delete/3f9a8c1e…",
"size": 184237,
"mime": "image/png",
"width": 1920,
"height": 1080,
"hash_sha256": "9b998a17f968480982526464f04575fc..."
}url is the direct image link — embed it anywhere a regular image URL works. delete_url is a one-shot delete link: anyone holding it can remove the upload with no key (DELETE or POST), so treat it like a secret.
curl -X DELETE https://upload.fixitfy.com.tr/api/delete/3f9a8c1e…
{ "ok": true, "deleted": "FIXITFY-aB3xZ7nQrL9p.png" }5. Error response
HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json
{
"ok": false,
"code": "nsfw_rejected",
"error": "Explicit content detected. This image cannot be hosted."
}Codes
unauthorized(401) — missing or malformedAuthorizationheaderbanned(403) — owner of the key is bannedmissing_file,empty_file,bad_request(400)too_large(413) — over 20 MBunsupported_type(415) — not a valid PNG/JPG/GIF/WebP/AVIFnsfw_rejected(415) — automated NSFW review blocked the uploadprocessing_failed(415) — image is corrupt or sharp couldn't decode itrate_limit(429) — 30 uploads per minute per keyrate_limit_day(429) — 2000 uploads per day per keystorage_failed,db_failed(500) — server error, retry with exponential backoff
6. Dedupe
Every upload's content is hashed (SHA-256). If you upload the exact same bytes twice, the second request returns the existing URL instead of writing a duplicate file. The hash is included in every success response.
7. Manage uploads & account
These read/management endpoints use the same Authorization: Bearer fxf_… header and return JSON. They share a per-key limit of 120 requests/min.
List your uploads
GET /api/v1/uploads?limit=50&before=<ISO> — newest first, cursor-paginated. Pass the response's next_before back as ?before= to page through.
curl -H "Authorization: Bearer fxf_YOUR_KEY" \
"https://upload.fixitfy.com.tr/api/v1/uploads?limit=50"
{
"ok": true,
"count": 50,
"next_before": "2026-05-01T12:00:00.000Z",
"uploads": [
{ "filename": "FIXITFY-aB3xZ7nQrL9p.png",
"url": "https://upload.fixitfy.com.tr/images/FIXITFY-aB3xZ7nQrL9p.png",
"mime": "image/png", "size": 184237, "width": 1920, "height": 1080,
"tags": ["redm","logo"], "created_at": "2026-05-01T11:59:00.000Z" }
]
}Look up one upload
GET /api/v1/uploads/:filename — full metadata for one of your uploads (404 not_found if it isn't yours or was deleted).
Delete an upload
DELETE /api/v1/uploads/:filename — soft-deletes it; the direct URL returns 404 immediately.
curl -X DELETE -H "Authorization: Bearer fxf_YOUR_KEY" \
https://upload.fixitfy.com.tr/api/v1/uploads/FIXITFY-aB3xZ7nQrL9p.png
{ "ok": true, "deleted": "FIXITFY-aB3xZ7nQrL9p.png" }Account & usage
GET /api/v1/me — your account stats plus this key's request count, for dashboards and quota displays.
{
"ok": true,
"account": { "email": "you@example.com", "role": "user",
"uploads_active": 128, "storage_used_bytes": 5242880 },
"key": { "prefix": "fxf_8350", "label": "ci",
"request_count": 402, "created_at": "2026-04-01T00:00:00.000Z" }
}8. Limits
- Max file size: 20 MB
- Per-key rate limit: 30/min, 2000/day
- Total active keys per user: 10
- Allowed formats: PNG, JPG (incl. JPEG), GIF, WebP, AVIF. EXIF metadata is stripped on upload.
9. Quick libraries
Node.js (fetch)
import { readFile } from "node:fs/promises";
const file = await readFile("./screenshot.png");
const fd = new FormData();
fd.set("file", new Blob([file], { type: "image/png" }), "screenshot.png");
const res = await fetch("https://upload.fixitfy.com.tr/api/v1/upload", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.FIXITFY_KEY },
body: fd,
});
const data = await res.json();
console.log(data.url);Python (requests)
import os, requests
with open("screenshot.png", "rb") as f:
r = requests.post(
"https://upload.fixitfy.com.tr/api/v1/upload",
headers={"Authorization": "Bearer " + os.environ["FIXITFY_KEY"]},
files={"file": f},
)
print(r.json()["url"])10. Webhooks
Register endpoints at /dashboard/webhooks. We POST an upload.created event to every enabled endpoint whenever you upload — through the website or the API.
Payload
POST https://your-server.com/webhooks/fixitfy
Content-Type: application/json
X-Fixitfy-Event: upload.created
X-Fixitfy-Signature: sha256=<hmac-hex>
{
"event": "upload.created",
"upload": {
"filename": "FIXITFY-aB3xZ7nQrL9p.png",
"url": "https://upload.fixitfy.com.tr/images/FIXITFY-aB3xZ7nQrL9p.png",
"size": 184237, "mime": "image/png", "width": 1920, "height": 1080,
"hash_sha256": "9b998a17f968480982526464f04575fc..."
},
"timestamp": "2026-06-01T12:00:00.000Z"
}Verifying the signature
Compute HMAC-SHA256(raw_body, signing_secret) and compare it (constant-time) to the hex value in X-Fixitfy-Signature. The secret is shown on the webhooks page.
import { createHmac, timingSafeEqual } from "node:crypto";
const received = req.headers["x-fixitfy-signature"].split("=")[1];
const expected = createHmac("sha256", SIGNING_SECRET).update(rawBody).digest("hex");
const valid = timingSafeEqual(Buffer.from(received), Buffer.from(expected));Respond with any 2xx. Non-2xx responses and timeouts (8 s) are recorded as failures on the webhook (visible in the dashboard).
11. Revoking a key
Visit /dashboard/api-keys and click Revoke next to any key. Revocation is instant — any in-flight request using that key returns 401 immediately.
If you suspect a key has been leaked, revoke it first, then generate a new one. Audit log entries (api_key.created / api_key.revoked) are visible to admins for incident review.