API documentation
Integrate imgtree from scripts, desktop tools, backends, or your own site. The stable surface for third parties is the Bearer API under /api/v1/ after you create a key in Settings.
- Discovery:
GET https://imgtree.co/api/v1/uploadreturns JSON limits and route hints for this deployment (no auth). - Typical flow: multipart
POST …/api/v1/upload, or presign →PUT→ complete for large files. - Browsers: prefer calling the API from your server; there is no public CORS policy for arbitrary browser origins.
API documentation
This reference is for webmasters and developers who integrate with imgtree: automation, mobile or desktop clients, forum tools (for example ShareX), or server-side scripts.
Base URL: use your site’s origin (for example https://img.example.com). All paths below are rooted at that origin.
Live limits: send an unauthenticated GET /api/v1/upload to receive JSON with the current max file size, allowed image types, rate-limit notes, and a short index of upload-related routes for this deployment.
Browser note: imgtree does not send broad Access-Control-* headers on the API. Call the API from your server or backend, or place your own proxy or edge rules if you need direct browser fetch from third-party pages.
API keys (recommended for integrations)
- Create a free account and sign in.
- Open Settings (or your dashboard’s API keys section) and create an API key.
- Copy the key when it is shown — it is only displayed once.
- Send it on every request as:
Authorization: Bearer <your_api_key>
The sections below describe the version 1 HTTP API (/api/v1/...), which uses this header. Keys are tied to your account; uploads count against your storage quota.
GET /api/v1/upload
Returns machine-readable capabilities for this instance: max upload size, allowed MIME types, presigned URL lifetime, batch limits, and brief endpoint descriptions. No Authorization header.
Use this in installers or scripts so you do not hard-code limits.
POST /api/v1/upload
Upload one or more images using multipart (typical for ShareX and form posts) or JSON with base64 for a single image (convenient from servers).
Multipart
Content-Type: multipart/form-data
Authorization: Bearer <your_api_key>
file: <binary> # repeat the field name "file" for multiple files
albumId: <uuid> # optional — must belong to your account
JSON (one image per request)
Content-Type: application/json
Authorization: Bearer <your_api_key>
{
"filename": "screenshot.png",
"contentType": "image/png",
"file_base64": "<base64 or data:image/png;base64,...>",
"albumId": "<optional uuid>"
}
The field base64 is accepted as an alias for file_base64.
Sizing: Base64 increases payload size. For large files, prefer multipart or the presign → PUT → complete flow below.
Unsupported Content-Type: the server responds with 415.
Image types: image/jpeg, image/png, image/gif, image/webp
Max size: Defined by this deployment (see GET /api/v1/upload). Multipart uploads may also be limited by your host’s maximum request body size.
Large files: Use POST /api/v1/upload/presign, PUT the bytes to put_url, then POST /api/v1/upload/complete with completion_token. That path bypasses your app server’s body limit for the main file.
Rate limiting: By default, about 30 requests per minute per client IP (see the discovery response for wording used on this instance).
Response 200
{
"success": true,
"images": [
{
"id": "abc12xyz",
"url": "https://{origin}/i/abc12xyz",
"direct_url": "https://…",
"thumb_url": "https://…",
"delete_url": "https://{origin}/api/images/<uuid>?token=<delete_token>",
"codes": {
"bbcode": "[img]https://…[/img]",
"bbcode_thumb": "[url=https://…][img]https://…/thumb[/img][/url]",
"html": "<img src=\"https://…\" alt=\"file.jpg\" />",
"markdown": "",
"direct": "https://…"
}
}
]
}
id is the image slug (public page /i/{slug}). delete_url uses the internal image UUID.
Common errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
403 | Account inactive |
429 | Too many requests |
400 | Bad request (for example no files) |
500 | Server error |
Per-file failures in multipart batches appear as objects with an error string instead of URLs.
POST /api/v1/upload/presign
Returns a time-limited URL to upload the original file bytes with PUT, using the same Content-Type you declare.
Request — Content-Type: application/json
{
"filename": "photo.jpg",
"contentType": "image/jpeg",
"sizeBytes": 1234567,
"albumId": "<optional uuid>"
}
Response 200
{
"put_url": "https://…",
"completion_token": "<opaque>"
}
Then: PUT to put_url with the raw bytes and header Content-Type matching contentType.
POST /api/v1/upload/presign/batch
Up to 20 presigns in one call (same auth and album rules as a single presign).
Request — Content-Type: application/json
{
"albumId": "<optional uuid>",
"files": [
{ "filename": "a.jpg", "contentType": "image/jpeg", "sizeBytes": 1000 },
{ "filename": "b.png", "contentType": "image/png", "sizeBytes": 2000 }
]
}
Response 200
{
"success": true,
"uploads": [
{ "put_url": "https://…", "completion_token": "…" },
{ "error": "Filename required", "status": 400 }
]
}
Order matches files. After each successful PUT, call complete or complete/batch with the matching tokens.
POST /api/v1/upload/complete
Request — Content-Type: application/json
{ "completion_token": "<from presign>" }
token is accepted as an alias.
Response 200 — Same shape as POST /api/v1/upload (success, images[]).
POST /api/v1/upload/complete/batch
Finalize up to 20 direct uploads after PUT to each put_url.
Request — Content-Type: application/json
{
"completion_tokens": ["<from presign>", "<from presign>"]
}
tokens is accepted as an alias for completion_tokens.
Response 200
{
"success": true,
"images": [
{ "id": "<slug>", "url": "…", "direct_url": "…", "thumb_url": "…", "delete_url": "…", "codes": { } },
{ "error": "Invalid or expired upload token" }
]
}
Order matches the input tokens. Your API key’s upload counter increases by the number of successful finalizations.
GET /api/v1/images
Lists images owned by the API key (not deleted), with pagination.
Query: page (default 1), limit (default 24, max 100).
Response 200
{
"success": true,
"images": [
{
"id": "<uuid>",
"slug": "…",
"url": "https://{origin}/i/{slug}",
"direct_url": "…",
"thumb_url": "…",
"original_name": "…",
"created_at": "…"
}
],
"page": 1,
"limit": 24,
"total": 42,
"has_more": true
}
DELETE /api/v1/images/[imageId]
Soft-deletes an image by UUID (imageId), using the API key. Behaviour matches an authenticated delete in the web app, without cookies.
ShareX (example custom uploader)
Replace the URL with your site and paste your API key:
{
"Name": "imgtree",
"DestinationType": "ImageUploader",
"RequestMethod": "POST",
"RequestURL": "https://{your-site}/api/v1/upload",
"Headers": {
"Authorization": "Bearer <your_api_key>"
},
"Body": "MultipartFormData",
"FileFormName": "file",
"URL": "$json:images[0].url$",
"ThumbnailURL": "$json:images[0].thumb_url$",
"DeletionURL": "$json:images[0].delete_url$"
}
Multipart vs presigned upload: ShareX’s single-request custom uploader works well with multipart POST /api/v1/upload. If your hosting enforces a small HTTP body limit (often a few megabytes), very large files may fail before they reach the app. For larger files, use presign → PUT → complete from a script or another client, or keep multipart uploads under the limit.
Signed-in session API (cookies)
These routes power the imgtree web app. They expect a logged-in browser session (session cookie), not the Bearer API key. Use them only if you are building tooling that runs as the signed-in user in a trusted environment.
Images
| Method | Path | Description |
|---|---|---|
GET | /api/images | Paginated list (page, limit ≤ 100) |
PATCH | /api/images/[imageId] | Update allowed fields (owner only) |
DELETE | /api/images/[imageId] | Soft delete; owner session or ?token=<delete_token> from a delete_url (rate limited) |
GET /api/images returns { images, page, limit, total, has_more }.
Albums
| Method | Path | Description |
|---|---|---|
GET | /api/albums | List albums |
POST | /api/albums | Create album |
GET | /api/albums/[albumId] | Album detail |
PATCH | /api/albums/[albumId] | Update album |
DELETE | /api/albums/[albumId] | Delete album |
API keys (session)
| Method | Path | Description |
|---|---|---|
GET | /api/keys | List keys (metadata only) |
POST | /api/keys | Create key (secret returned once) |
DELETE | /api/keys/[keyId] | Revoke key |
Upload (session and guest)
| Method | Path | Description |
|---|---|---|
POST | /api/upload | Signed-in multipart (files, optional albumId, isPublic) |
POST | /api/upload/presign | Presign for signed-in user |
POST | /api/upload/complete | Complete after PUT (session) |
POST | /api/upload/guest | Public multipart upload |
POST | /api/upload/guest/presign | Guest presign |
POST | /api/upload/guest/complete | Guest complete after PUT |
Operator API (admin only)
Reserved for accounts with the admin role.
| Method | Path | Description |
|---|---|---|
GET | /api/admin/stats | Aggregated statistics |
GET | /api/admin/users | User list / search |
PATCH | /api/admin/users/[userId] | Update user (role, active state, quota, etc.) |