{
  "name": "image-resize",
  "summary": "Resizes an image to a target width/height under a chosen fit, returned base64-encoded.",
  "rationale": "Resizing safely needs a real decoder and a hardened fetch: an agent that pulls the URL itself walks past every SSRF control, and the output must be byte-reproducible, which an ad-hoc resample is not.",
  "family": "images",
  "price_usd": "0.003",
  "free": false,
  "timeout_ms": 60000,
  "max_timeout_seconds": 81,
  "input_schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "maxLength": 2048,
        "format": "uri",
        "description": "Absolute http(s) URL of the source image, up to 2048 characters; redirects are followed, the bytes must be jpeg, png, gif, webp, tiff, avif, heic or svg by signature, and at most 40 megapixels."
      },
      "width": {
        "description": "Target width in pixels, 1 to 20000; at least one of width or height is required, and a missing side follows the aspect ratio (except under fill).",
        "type": "integer",
        "minimum": 1,
        "maximum": 20000
      },
      "height": {
        "description": "Target height in pixels, 1 to 20000; at least one of width or height is required, and a missing side follows the aspect ratio (except under fill).",
        "type": "integer",
        "minimum": 1,
        "maximum": 20000
      },
      "fit": {
        "default": "inside",
        "description": "How the image fills the target box, as in sharp: inside fits within keeping the ratio (default), cover crops from the centre, contain pads to the full box, fill stretches, outside covers the box without cropping.",
        "type": "string",
        "enum": [
          "cover",
          "contain",
          "fill",
          "inside",
          "outside"
        ]
      },
      "format": {
        "description": "Output format; when omitted the source format is kept if it is png, jpeg or webp, otherwise the output is PNG.",
        "type": "string",
        "enum": [
          "png",
          "jpeg",
          "webp"
        ]
      },
      "quality": {
        "default": 80,
        "description": "Encoder quality from 1 to 100, default 80, used by the lossy jpeg and webp encoders and ignored for png.",
        "type": "integer",
        "minimum": 1,
        "maximum": 100
      },
      "allow_enlarge": {
        "default": false,
        "description": "When true the image may be scaled up past its native size; default false keeps each side at most its source size.",
        "type": "boolean"
      }
    },
    "required": [
      "url"
    ],
    "additionalProperties": false
  },
  "input_example": {
    "url": "https://grist.tools/samples/images/tiles-64x40.png",
    "width": 32,
    "fit": "inside"
  },
  "output_example": {
    "source_url": "https://grist.tools/samples/images/tiles-64x40.png",
    "source_format": "png",
    "source_width": 64,
    "source_height": 40,
    "format": "png",
    "mime_type": "image/png",
    "fit": "inside",
    "width": 32,
    "height": 20,
    "bytes": 779,
    "image_base64": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAUCAYAAADskT9PAAAACXBIWXMAAAsSAAAL..."
  },
  "errors": [
    "invalid_input",
    "blocked_target",
    "unreachable_target",
    "upstream_timeout",
    "unsupported_content_type",
    "too_large",
    "unprocessable",
    "internal"
  ]
}