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/upload returns 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)

  1. Create a free account and sign in.
  2. Open Settings (or your dashboard’s API keys section) and create an API key.
  3. Copy the key when it is shown — it is only displayed once.
  4. 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": "![file.jpg](https://…)",
        "direct": "https://…"
      }
    }
  ]
}

id is the image slug (public page /i/{slug}). delete_url uses the internal image UUID.

Common errors

StatusMeaning
401Missing or invalid API key
403Account inactive
429Too many requests
400Bad request (for example no files)
500Server 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.

RequestContent-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).

RequestContent-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

RequestContent-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.

RequestContent-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

MethodPathDescription
GET/api/imagesPaginated 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

MethodPathDescription
GET/api/albumsList albums
POST/api/albumsCreate album
GET/api/albums/[albumId]Album detail
PATCH/api/albums/[albumId]Update album
DELETE/api/albums/[albumId]Delete album

API keys (session)

MethodPathDescription
GET/api/keysList keys (metadata only)
POST/api/keysCreate key (secret returned once)
DELETE/api/keys/[keyId]Revoke key

Upload (session and guest)

MethodPathDescription
POST/api/uploadSigned-in multipart (files, optional albumId, isPublic)
POST/api/upload/presignPresign for signed-in user
POST/api/upload/completeComplete after PUT (session)
POST/api/upload/guestPublic multipart upload
POST/api/upload/guest/presignGuest presign
POST/api/upload/guest/completeGuest complete after PUT

Operator API (admin only)

Reserved for accounts with the admin role.

MethodPathDescription
GET/api/admin/statsAggregated statistics
GET/api/admin/usersUser list / search
PATCH/api/admin/users/[userId]Update user (role, active state, quota, etc.)

← Back to upload