JIEZO API Documentation

JIEZO exposes a small public HTTP API: capture a live web page as an image, recompress an exported image, resolve a tweet, and proxy Twitter media. There is no API key, no token, and no account. Every failing request returns the same JSON error envelope. The machine-readable contract lives at /openapi.json.

Quickstart

Capture a page and write the PNG to disk in one command.

curl -s -X POST https://kimte.com/api/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}' \
  | jq -r .screenshot | base64 -d > shot.png

Base URL

https://kimte.com

Endpoints

POST/api/screenshot

operationId: captureScreenshot

Renders the page at the given URL and returns the screenshot as a base64-encoded PNG. Results are cached per URL, device type, and color scheme.

Request

curl -X POST https://kimte.com/api/screenshot \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "deviceType": "desktop",
    "colorScheme": "light",
    "forceRefresh": false
  }'

Response

{
  "screenshot": "iVBORw0KGgoAAAANSUhEUg...",
  "url": "https://example.com",
  "cached": false,
  "strategy": "microlink",
  "deviceType": "desktop",
  "colorScheme": "light"
}

POST/api/export

operationId: optimizeExportImage

Recompresses an image with Sharp and returns the optimized bytes. JPEG uses MozJPEG, WebP uses libwebp, PNG uses adaptive filtering. The response body is the image itself, not JSON.

Request

curl -X POST https://kimte.com/api/export \
  -F "image=@shot.png" \
  -F "format=webp" \
  -F "qualityPreset=high" \
  -o shot.webp

Response

HTTP/2 200
content-type: image/webp

<binary image bytes>

GET/api/tweet/{id}

operationId: getTweet

Returns the public tweet payload used to render a tweet as an image. The id is the numeric status ID from the tweet URL.

Request

curl https://kimte.com/api/tweet/1234567890123456789

Response

{
  "data": {
    "id_str": "1234567890123456789",
    "text": "...",
    "user": { "name": "...", "screen_name": "..." }
  }
}

GET/api/image-proxy

operationId: proxyTwitterImage

Streams a Twitter-hosted image through this origin so it can be drawn onto a canvas without tainting it. Only pbs.twimg.com, abs.twimg.com, ton.twitter.com, and video.twimg.com are allowed.

Request

curl "https://kimte.com/api/image-proxy?url=https://pbs.twimg.com/media/EXAMPLE.jpg" \
  -o media.jpg

Response

HTTP/2 200
content-type: image/jpeg

<binary image bytes>

Errors

Every failing request returns JSON with the same shape. Branch on code, which is stable; error and message carry the same human-readable text, and hint explains how to recover.

{
  "error": "URL is required",
  "code": "invalid_request",
  "message": "URL is required",
  "hint": "Send a JSON body with a \"url\" string, for example {\"url\": \"https://example.com\"}.",
  "status": 400,
  "documentation": "https://kimte.com/docs#errors"
}
CodeStatusMeaning
invalid_request400A required field is missing or malformed.
invalid_url400The url is not a valid absolute http or https URL.
unsupported_value400A field was set to a value outside its allowed enum.
forbidden_domain403The requested host is not on the proxy allowlist.
not_found404No endpoint or resource matches the request.
method_not_allowed405The endpoint does not accept this HTTP method.
rate_limited429The per-IP rate limit was exceeded. Honour Retry-After.
upstream_timeout408The target page took too long to load.
upstream_unavailable503The upstream capture service is unreachable.
upstream_failed502The upstream host refused or failed the request.
internal_error500Unexpected server-side failure.

Markdown content negotiation

Every page on this site serves Markdown to clients that ask for it. Responses set Content-Type: text/markdown; charset=utf-8 and Vary: Accept, Accept-Encoding. A request that accepts neither text/html nor text/markdown is answered with 406, and an unknown path returns 404 with a Markdown body listing where to look next.

curl -H "Accept: text/markdown" https://kimte.com/

Related resources