# img.pro > Image hosting and transformation API. Upload an image, get a shareable URL that resizes, crops, and converts on the fly. One request to start, no account required. ## Quick Start `POST /v1/images` is the single create endpoint — send a file or a URL. Upload a file: ```bash curl -X POST https://api.img.pro/v1/images -F "file=@photo.jpg" ``` Or import from a URL (the server negotiates by Content-Type: `application/json` → URL import, multipart → file upload): ```bash curl -X POST https://api.img.pro/v1/images \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/photo.jpg"}' ``` Response: ```json { "id": "abc12345", "object": "image", "url": "https://src.img.pro/4j2/abc12345.jpg", "page_url": "https://img.pro/abc12345", "sizes": { "small": { "url": "https://src.img.pro/4j2/abc12345.jpg?size=s", "width": 426, "height": 320 }, "medium": { "url": "https://src.img.pro/4j2/abc12345.jpg?size=m", "width": 853, "height": 640 }, "large": { "url": "https://src.img.pro/4j2/abc12345.jpg?size=l", "width": 1440, "height": 1080 } }, "filename": "photo.jpg", "format": "jpg", "width": 4000, "height": 3000, "bytes": 245678, "transformable": true, "status": "ready", "public": true, "published_at": "2024-01-01T00:00:00Z", "expires_at": null, "created_at": "2024-01-01T00:00:00Z", "caption": null, "metadata": {}, "labels": {}, "nsfw": false } ``` - `url` — the image itself; a direct, embeddable CDN URL you transform via query params (e.g. `?format=webp&w=800`). Always present, every plan. - `page_url` — the canonical viewer page on img.pro; the link you send to a human. Always returned, but it 404s for outsiders when `public` is false — embed `url` for private images. - `sizes` — three ready-made responsive variants (small/medium/large), each with a `url` + dims. Empty `{}` for non-transformable sources. For a social/OG card, add `?size=social` to the `url`. - `format` — output format, normalized (HEIC stored as JPG returns `"jpg"`). - `metadata` — nested object of your custom fields (author, license, …); `{}` when empty. - `labels` — nested object of your selector labels (state, kind, …); `{}` when empty. The queryable sibling of `metadata`: filter lists with `?label[key]=value`. - `expires_at` — ISO-8601 UTC, or `null` for permanent. `published_at` — ISO-8601 UTC display timestamp (never `null`; defaults to upload time); lists sort by it newest-first. - Every field is always present (`null`/`{}`/`false` when empty), never omitted. Anonymous uploads also return a signup nudge in the `X-Img-Action` response header — the body stays a pure resource. ## Authentication Three ways to call the API, picked by whose images you act on: - **Anonymous** — no credential. Uploads are always public (visibility isn't configurable here — every explicit false form for `public` returns `422`), expire in 30 days, cap at 20 MB, and are rate-limited. Good for trying it; can't list/update/delete. - **API key** — your own account. Send `Authorization: Bearer img_live_…` (keys look like `img_live_…`). Uploads are permanent and yours to manage. Create a key at https://img.pro/keys. Keys carry `read` and/or `write` abilities. - **App** — your users' accounts. Your backend holds one machine secret (`img_sk_live_…`) and names the user with an `X-Img-User` header; no OAuth, no per-user tokens. See https://img.pro/api/app and the App API section in llms-full.txt. ```bash curl -X POST https://api.img.pro/v1/images \ -H "Authorization: Bearer img_live_…" \ -F "file=@photo.jpg" \ -F "caption=Hero shot from launch day" ``` ## Transformations The `url` field is a direct CDN URL — append query parameters to transform on the fly. Always present, every plan; each distinct URL is cached at the edge. | Param | Values | Description | |-------|--------|-------------| | size | s, m, l, social | Named preset. s/m/l constrain the short side to 320/640/1080px (aspect preserved); social is a fixed 1200×630 OpenGraph card. Skips the manual params below. | | format | jpg, png, webp, avif, gif | Output format. Overrides the path extension. webp = best size/quality; png = lossless + transparency. No `auto` (client-dependent, unsafe with shared caching). | | w, h | 1–4096 (px) | Target width / height. Set one to scale proportionally, or both with `fit`. | | fit | scale-down (default), contain, cover, crop, pad, squeeze | How the image fills w×h. cover/crop fill and trim; contain/pad letterbox; scale-down never enlarges. | | gravity | auto (default), face, left, right, top, bottom | Which part to keep when cropping. face centers on detected faces. | | zoom | 0–1 | Crop tightness around gravity=face (0 = most context, 1 = tight). | | q | 1–100, or high / medium-high / medium-low / low | Quality for lossy formats (JPEG/WebP/AVIF). Named levels ≈ 90/75/60/45. No effect on PNG (always lossless). | | brightness | 0–10 (default 1) | Multiplier. 0 = black, 2 = twice as bright. Useful ~0.5–2. | | contrast | 0–10 (default 1) | Multiplier. >1 = punchier. Useful ~0.7–2. | | gamma | 0–10 (default 1) | Multiplier. <1 lightens midtones, >1 darkens (0 and 1 are no-ops). Useful ~0.5–2.5. | | saturation | 0–10 (default 1) | Multiplier. 0 = grayscale, >1 = vivid. Useful ~0.5–2. | | blur | 0–250 (default 0) | Gaussian blur radius in pixels. | | sharp | 0–10 (default 0) | Unsharp-mask intensity. | | rotate | 90, 180, 270 | Clockwise rotation in degrees. | | flip | h, v, hv | Mirror horizontally, vertically, or both. | | trim | border | Auto-crop a uniform border color around the image. | | metadata | copyright (default), none, keep | EXIF retention. copyright strips GPS/device but keeps copyright tags; none strips all; keep retains all (incl. GPS). | | segment | foreground | Remove the background (edge segmentation). Add format=png to keep transparency. | | background | CSS named color, #hex (URL-encode # as %23), rgb(...), rgba(...) | Fill color for transparent areas. Pair with segment=foreground to swap the background; alone it fills transparent pixels. When omitted, alpha-capable formats stay transparent and others fill white. | | fx | blur-bg, color-pop, darken-bg | One-param composite (subject stays sharp, effect on the background). blur-bg = portrait blur; color-pop = grayscale background; darken-bg = spotlight. | | strength | per recipe | Tunes fx (only with fx). blur-bg: radius 0–250 (default 60). darken-bg: brightness 0.05–1 (default 0.5). color-pop: none. Out-of-range clamps. | | tile | An image id (same workspace) | Watermark — tile another of your images across the base. Cross-workspace / unknown ids are ignored. Design it as a seamless transparent PNG. | Examples: ``` https://src.img.pro/4j2/abc12345.jpg?size=m https://src.img.pro/4j2/abc12345.jpg?format=webp&w=800 https://src.img.pro/4j2/abc12345.jpg?segment=foreground&background=white&format=jpg https://src.img.pro/4j2/abc12345.jpg?fx=blur-bg ``` See https://img.pro/api/transforms for the full reference. ## Plans | Plan | Uploads/mo | Storage | Retention | Price | |------|-----------|---------|-----------|-------| | Anonymous | Rate-limited | Shared | 30 days | Free | | Free | 1,000/mo | 10 GB | Permanent | Free | | Pro | 10,000/mo | 100 GB | Permanent | $29/mo | | Scale | 50,000/mo | 500 GB | Permanent | $99/mo | | Max | 200,000/mo | 2 TB | Permanent | $199/mo | ## Error Handling Every error is one nested `error` object: branch on `error.type` (coarse) or switch on `error.code` (specific). When present, `error.action.type` is a closed enum telling you what to do: - `upgrade` — quota reached; show `action.url` (signed upgrade link, or billing for top-tier accounts) - `wait` — rate limited; retry after `action.retry_after` seconds (also in the `Retry-After` header) - `signup` — anonymous `quota_exceeded` carries it (shared free workspace at its cap); `action.url` is the registration page. The nudge on a *successful* anonymous upload rides `X-Img-Action` instead ## Building an App Everything above uses your OWN API key. To build an app where YOUR users sign in to img.pro and you act on their images + billing, use the App API: hosted login (`img.pro/connect`) → exchange a one-time code for a verified `user` → act with one machine secret (`img_sk_`) + an `X-Img-User` header. Register at https://img.pro/apps. Full flow: https://img.pro/api/app (and in llms-full.txt). ## Full Reference - Complete API reference: https://img.pro/llms-full.txt - Interactive docs: https://img.pro/api - Authentication: https://img.pro/api/authentication - Building an app (App API): https://img.pro/api/app - Transformations: https://img.pro/api/transforms - OpenAPI spec: https://img.pro/openapi.yaml