# Image APIs API reference

Render social cards, Open Graph images, banners, certificates and PDFs from JSON layer templates or your own HTML; screenshot public pages; build signed URLs that render on first fetch. Every render returns a hosted URL. Costs are in images: one per image or screenshot, one per PDF page; template and record reads are free. Plan ceilings are reported on every response in the `X-Gw-*` headers (`X-Gw-Remaining`, `X-Gw-Reset`), so clients and agents can pace themselves.

Base URL: `https://api.imageapis.com/`. Send your key in the `X-API-Key` header; the remaining allowance comes back on every response in `X-Gw-Remaining`.

MCP server: `https://mcp.imageapis.com/` (bearer token = the same key).

## Errors every operation can return

- `400` A parameter is missing, malformed or out of range

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

# Images

# Images

## POST /v1/images

**Render an image from a template, an inline template or HTML**

One request, one image. Pass a stored template's id with `modifications` and `variables`, an inline template object, or raw `html`. The response carries a hosted `url` (30 days on Free, a year on paid plans). Set `response` to `binary` to get the file itself, or `webhook_url` to render in the background.

### Request body (application/json)

```json
{
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "modifications": [
    {
      "name": "title",
      "text": "Launch week starts Monday"
    },
    {
      "name": "photo",
      "src": "https://example.com/hero.jpg"
    }
  ],
  "format": "png",
  "scale": 2
}
```

### Responses

- `200` With response=binary: the file itself, with X-Image-Id and X-Image-Url headers
- `201` Created

```json
{
  "id": "img_7hk2mq9ztbw4e6nrcxpd",
  "object": "image",
  "status": "completed",
  "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
  "format": "png",
  "width": 1200,
  "height": 630,
  "scale": 1,
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "bytes": 48213,
  "units": 1,
  "created": "2026-10-10T18:04:11Z",
  "completed": "2026-10-10T18:04:12Z",
  "expires": "2026-11-09T18:04:11Z"
}
```

- `202` Accepted: rendering in the background; the record has status pending and the webhook gets the finished one

```json
{
  "id": "img_7hk2mq9ztbw4e6nrcxpd",
  "object": "image",
  "status": "completed",
  "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
  "format": "png",
  "width": 1200,
  "height": 630,
  "scale": 1,
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "bytes": 48213,
  "units": 1,
  "created": "2026-10-10T18:04:11Z",
  "completed": "2026-10-10T18:04:12Z",
  "expires": "2026-11-09T18:04:11Z"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/images" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "modifications": [
    {
      "name": "title",
      "text": "Launch week starts Monday"
    },
    {
      "name": "photo",
      "src": "https://example.com/hero.jpg"
    }
  ],
  "format": "png",
  "scale": 2
}'
```

## GET /v1/images/{id}

**Fetch an image's record: status, url, size**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The image id Example: img_7hk2mq9ztbw4e6nrcxpd |

### Responses

- `200` OK

```json
{
  "id": "img_7hk2mq9ztbw4e6nrcxpd",
  "object": "image",
  "status": "completed",
  "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
  "format": "png",
  "width": 1200,
  "height": 630,
  "scale": 1,
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "bytes": 48213,
  "units": 1,
  "created": "2026-10-10T18:04:11Z",
  "completed": "2026-10-10T18:04:12Z",
  "expires": "2026-11-09T18:04:11Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/images/img_7hk2mq9ztbw4e6nrcxpd" \
  -H "X-API-Key: YOUR_KEY"
```

# Collections

# Collections

## POST /v1/collections

**Render many images from one template in a single request**

One template, up to 50 sets of variables and modifications, one call. The response is 202 with every image's id and final url already assigned; renders run in the background, five at a time. Poll GET /v1/collections/{id}, or pass webhook_url to be told when the whole set is done. Costs one image per item, charged up front.

### Request body (application/json)

```json
{
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "items": [
    {
      "variables": {
        "title": "Post one"
      },
      "metadata": {
        "post": 101
      }
    },
    {
      "variables": {
        "title": "Post two"
      },
      "metadata": {
        "post": 102
      }
    }
  ],
  "scale": 2
}
```

### Responses

- `200` With response=binary: the file itself, with X-Image-Id and X-Image-Url headers
- `202` Accepted: rendering in the background; the record has status pending and the webhook gets the finished one

```json
{
  "id": "col_5kq2wz8xmtnb4hdc7vre",
  "object": "collection",
  "status": "pending",
  "total": 2,
  "completed": 0,
  "failed": 0,
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "format": "png",
  "scale": 1,
  "units": 2,
  "images": [
    {
      "index": 0,
      "id": "img_7hk2mq9ztbw4e6nrcxpd",
      "status": "pending",
      "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
      "metadata": {
        "post": 101
      }
    },
    {
      "index": 1,
      "id": "img_9xw4nq2kdtbz7hmc3vpe",
      "status": "pending",
      "url": "https://img.imageapis.com/i/img_9xw4nq2kdtbz7hmc3vpe.png",
      "metadata": {
        "post": 102
      }
    }
  ],
  "created": "2026-10-10T19:02:11Z",
  "expires": "2026-11-09T19:02:11Z"
}
```

- `401` Missing or invalid API key (from the gateway)

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/collections" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "items": [
    {
      "variables": {
        "title": "Post one"
      },
      "metadata": {
        "post": 101
      }
    },
    {
      "variables": {
        "title": "Post two"
      },
      "metadata": {
        "post": 102
      }
    }
  ],
  "scale": 2
}'
```

## GET /v1/collections/{id}

**A collection's progress and its images**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The collection id Example: col_5kq2wz8xmtnb4hdc7vre |

### Responses

- `200` OK

```json
{
  "id": "col_5kq2wz8xmtnb4hdc7vre",
  "object": "collection",
  "status": "completed",
  "total": 2,
  "completed": 2,
  "failed": 0,
  "template": "tpl_4nq8vzk2hdyw7bxme3rc",
  "format": "png",
  "scale": 1,
  "units": 2,
  "images": [
    {
      "index": 0,
      "id": "img_7hk2mq9ztbw4e6nrcxpd",
      "status": "completed",
      "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
      "bytes": 48213,
      "metadata": {
        "post": 101
      }
    },
    {
      "index": 1,
      "id": "img_9xw4nq2kdtbz7hmc3vpe",
      "status": "completed",
      "url": "https://img.imageapis.com/i/img_9xw4nq2kdtbz7hmc3vpe.png",
      "bytes": 51022,
      "metadata": {
        "post": 102
      }
    }
  ],
  "created": "2026-10-10T19:02:11Z",
  "completed_at": "2026-10-10T19:02:19Z",
  "expires": "2026-11-09T19:02:11Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/collections/col_5kq2wz8xmtnb4hdc7vre" \
  -H "X-API-Key: YOUR_KEY"
```

# Templates

# Templates

## GET /v1/templates

**List this account's templates**

### Responses

- `200` OK

```json
{
  "templates": [
    {
      "id": "tpl_4nq8vzk2hdyw7bxme3rc",
      "object": "template",
      "name": "Blog post card",
      "engine": "layers",
      "width": 1200,
      "height": 630,
      "layers": 3,
      "created": "2026-10-10T17:40:02Z",
      "updated": "2026-10-10T17:40:02Z"
    }
  ]
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/templates" \
  -H "X-API-Key: YOUR_KEY"
```

## POST /v1/templates

**Save a template: positioned layers, or your own HTML**

Layers are rendered bottom to top inside a canvas of width × height. Text layers shrink to fit their box by default. Put `{{placeholders}}` in text, src, html or css and fill them with `variables` at render time, or override any layer property by name with `modifications`. Set `engine` to `html` to bring your own HTML and CSS instead of layers.

### Request body (application/json)

```json
{
  "name": "Blog post card",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ]
}
```

### Responses

- `201` Created

```json
{
  "id": "tpl_4nq8vzk2hdyw7bxme3rc",
  "object": "template",
  "name": "Blog post card",
  "engine": "layers",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ],
  "created": "2026-10-10T17:40:02Z",
  "updated": "2026-10-10T17:40:02Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/templates" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Blog post card",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ]
}'
```

## GET /v1/templates/{id}

**One template with all its layers**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The template id Example: tpl_4nq8vzk2hdyw7bxme3rc |

### Responses

- `200` OK

```json
{
  "id": "tpl_4nq8vzk2hdyw7bxme3rc",
  "object": "template",
  "name": "Blog post card",
  "engine": "layers",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ],
  "created": "2026-10-10T17:40:02Z",
  "updated": "2026-10-10T17:40:02Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/templates/tpl_4nq8vzk2hdyw7bxme3rc" \
  -H "X-API-Key: YOUR_KEY"
```

## PUT /v1/templates/{id}

**Replace a template's definition**

Send the whole template; what you send is what is kept. Renders already made from it are unaffected; signed URLs pick up the new version.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The template id Example: tpl_4nq8vzk2hdyw7bxme3rc |

### Request body (application/json)

```json
{
  "name": "Blog post card",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ]
}
```

### Responses

- `200` OK

```json
{
  "id": "tpl_4nq8vzk2hdyw7bxme3rc",
  "object": "template",
  "name": "Blog post card",
  "engine": "layers",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ],
  "created": "2026-10-10T17:40:02Z",
  "updated": "2026-10-10T17:40:02Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl -X PUT "https://api.imageapis.com/v1/templates/tpl_4nq8vzk2hdyw7bxme3rc" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Blog post card",
  "width": 1200,
  "height": 630,
  "background": "#0b1220",
  "layers": [
    {
      "name": "title",
      "type": "text",
      "x": 72,
      "y": 160,
      "width": 1056,
      "height": 280,
      "text": "{{title}}",
      "font": "Inter",
      "weight": 800,
      "size": 72,
      "color": "#ffffff",
      "fit": "shrink",
      "max_lines": 3
    },
    {
      "name": "site",
      "type": "text",
      "x": 72,
      "y": 72,
      "width": 600,
      "height": 40,
      "text": "apidirectory.com",
      "font": "Inter",
      "weight": 600,
      "size": 28,
      "color": "#a3b1c6"
    },
    {
      "name": "accent",
      "type": "rect",
      "x": 0,
      "y": 616,
      "width": 1200,
      "height": 14,
      "fill": "#6366f1"
    }
  ]
}'
```

## DELETE /v1/templates/{id}

**Delete a template**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The template id Example: tpl_4nq8vzk2hdyw7bxme3rc |

### Responses

- `200` OK

```json
{
  "id": "tpl_4nq8vzk2hdyw7bxme3rc",
  "object": "template",
  "deleted": true
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl -X DELETE "https://api.imageapis.com/v1/templates/tpl_4nq8vzk2hdyw7bxme3rc" \
  -H "X-API-Key: YOUR_KEY"
```

# Starters

# Starters

## GET /v1/starters

**Starter templates to copy: social cards, a ticket with a QR code, a certificate, a video thumbnail**

Each starter is a complete template with {{placeholders}} and sample variables. Render one inline by passing its `template` to POST /v1/images, or save your own copy with POST /v1/templates and change it from there.

### Responses

- `200` OK

```json
{
  "starters": [
    {
      "slug": "og-card",
      "name": "Open Graph card",
      "description": "Site name, tag, a title that shrinks to fit, a description and an accent bar. The design behind POST /v1/og, as a template you can change.",
      "tags": [
        "social",
        "og"
      ],
      "width": 1200,
      "height": 630,
      "layers": 5,
      "variables": [
        "title",
        "description",
        "site",
        "tag"
      ]
    },
    {
      "slug": "event-ticket",
      "name": "Event ticket with QR",
      "description": "A wide ticket: event, date and venue on the left, the holder's name and seat, a perforation, and a QR code of the ticket URL on the right.",
      "tags": [
        "ticket",
        "qr",
        "pdf"
      ],
      "width": 1000,
      "height": 400,
      "layers": 10,
      "variables": [
        "event",
        "date",
        "venue",
        "name",
        "seat",
        "ticket_url"
      ]
    }
  ]
}
```

- `401` Missing or invalid API key (from the gateway)
- `429` Plan ceiling or rate limit reached; see X-Gw-Reset (from the gateway)

### Example

```bash
curl "https://api.imageapis.com/v1/starters" \
  -H "X-API-Key: YOUR_KEY"
```

## GET /v1/starters/{slug}

**One starter template with its layers and sample variables**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `slug` | path | string | yes | The starter's slug Example: event-ticket |

### Responses

- `200` OK

```json
{
  "slug": "og-card",
  "name": "Open Graph card",
  "description": "Site name, tag, a title that shrinks to fit, a description and an accent bar. The design behind POST /v1/og, as a template you can change.",
  "tags": [
    "social",
    "og"
  ],
  "width": 1200,
  "height": 630,
  "layers": 5,
  "variables": {
    "title": "Ship social cards without a designer",
    "description": "One request, one hosted image.",
    "site": "example.com",
    "tag": "Blog"
  },
  "template": {
    "name": "Open Graph card",
    "width": 1200,
    "height": 630,
    "background": "#0b1220",
    "layers": [
      {
        "name": "site",
        "type": "text",
        "x": 72,
        "y": 72,
        "width": 800,
        "height": 40,
        "text": "{{site}}",
        "font": "Inter",
        "weight": 600,
        "size": 28,
        "color": "#a3b1c6",
        "valign": "middle"
      },
      {
        "name": "tag",
        "type": "text",
        "x": 72,
        "y": 150,
        "width": 800,
        "height": 32,
        "text": "{{tag}}",
        "font": "Inter",
        "weight": 700,
        "size": 22,
        "color": "#6366f1",
        "transform": "uppercase",
        "letter_spacing": 2
      },
      {
        "name": "title",
        "type": "text",
        "x": 72,
        "y": 196,
        "width": 1056,
        "height": 230,
        "text": "{{title}}",
        "font": "Inter",
        "weight": 800,
        "size": 72,
        "color": "#ffffff",
        "valign": "bottom",
        "line_height": 1.08,
        "fit": "shrink",
        "max_lines": 3,
        "letter_spacing": -1
      },
      {
        "name": "description",
        "type": "text",
        "x": 72,
        "y": 442,
        "width": 1056,
        "height": 100,
        "text": "{{description}}",
        "font": "Inter",
        "weight": 400,
        "size": 30,
        "color": "#a3b1c6",
        "fit": "shrink",
        "max_lines": 2,
        "line_height": 1.35
      },
      {
        "name": "accent",
        "type": "rect",
        "x": 0,
        "y": 616,
        "width": 1200,
        "height": 14,
        "fill": "#6366f1"
      }
    ]
  }
}
```

- `401` Missing or invalid API key (from the gateway)
- `429` Plan ceiling or rate limit reached; see X-Gw-Reset (from the gateway)

### Example

```bash
curl "https://api.imageapis.com/v1/starters/event-ticket" \
  -H "X-API-Key: YOUR_KEY"
```

# Og

# Og

## POST /v1/og

**An Open Graph card from a title and a few options, no template needed**

A 1200×630 social card in the built-in design: site name and logo, an optional tag, the title (shrinks to fit), a description and an accent bar. For a card that renders on demand from a URL, create a signed base and use the template name `og`.

### Request body (application/json)

```json
{
  "title": "Three data stories from OpenFEC, NHTSA and OpenAlex",
  "description": "What 2.3 million rows say about September",
  "site": "apidirectory.com",
  "tag": "Blog",
  "theme": "dark",
  "accent": "#6366f1"
}
```

### Responses

- `200` With response=binary: the file itself, with X-Image-Id and X-Image-Url headers
- `201` Created

```json
{
  "id": "img_7hk2mq9ztbw4e6nrcxpd",
  "object": "image",
  "status": "completed",
  "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
  "format": "png",
  "width": 1200,
  "height": 630,
  "scale": 1,
  "template": "og",
  "bytes": 48213,
  "units": 1,
  "created": "2026-10-10T18:04:11Z",
  "completed": "2026-10-10T18:04:12Z",
  "expires": "2026-11-09T18:04:11Z"
}
```

- `202` Accepted: rendering in the background; the record has status pending and the webhook gets the finished one

```json
{
  "id": "img_7hk2mq9ztbw4e6nrcxpd",
  "object": "image",
  "status": "completed",
  "url": "https://img.imageapis.com/i/img_7hk2mq9ztbw4e6nrcxpd.png",
  "format": "png",
  "width": 1200,
  "height": 630,
  "scale": 1,
  "template": "og",
  "bytes": 48213,
  "units": 1,
  "created": "2026-10-10T18:04:11Z",
  "completed": "2026-10-10T18:04:12Z",
  "expires": "2026-11-09T18:04:11Z"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/og" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Three data stories from OpenFEC, NHTSA and OpenAlex",
  "description": "What 2.3 million rows say about September",
  "site": "apidirectory.com",
  "tag": "Blog",
  "theme": "dark",
  "accent": "#6366f1"
}'
```

# Pdfs

# Pdfs

## POST /v1/pdfs

**Make a PDF from a template, HTML or a public URL**

Costs one unit per page. A template without `format` prints at its own pixel size, one page; HTML and URLs paginate at the paper size you pick.

### Request body (application/json)

```json
{
  "html": "<h1>Invoice #1042</h1><p>Total due: $420.00</p>",
  "format": "A4",
  "margin": "20mm"
}
```

### Responses

- `200` With response=binary: the file itself, with X-Image-Id and X-Image-Url headers
- `201` Created

```json
{
  "id": "pdf_2wq9tkz7hvbx4nmc8rde",
  "object": "pdf",
  "status": "completed",
  "url": "https://img.imageapis.com/i/pdf_2wq9tkz7hvbx4nmc8rde.pdf",
  "format": "pdf",
  "pages": 2,
  "bytes": 90412,
  "units": 2,
  "created": "2026-10-10T18:10:40Z",
  "completed": "2026-10-10T18:10:42Z",
  "expires": "2026-11-09T18:10:40Z"
}
```

- `202` Accepted: rendering in the background; the record has status pending and the webhook gets the finished one

```json
{
  "id": "pdf_2wq9tkz7hvbx4nmc8rde",
  "object": "pdf",
  "status": "completed",
  "url": "https://img.imageapis.com/i/pdf_2wq9tkz7hvbx4nmc8rde.pdf",
  "format": "pdf",
  "pages": 2,
  "bytes": 90412,
  "units": 2,
  "created": "2026-10-10T18:10:40Z",
  "completed": "2026-10-10T18:10:42Z",
  "expires": "2026-11-09T18:10:40Z"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/pdfs" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "html": "<h1>Invoice #1042</h1><p>Total due: $420.00</p>",
  "format": "A4",
  "margin": "20mm"
}'
```

## GET /v1/pdfs/{id}

**Fetch a PDF's record**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The PDF id Example: pdf_2wq9tkz7hvbx4nmc8rde |

### Responses

- `200` OK

```json
{
  "id": "pdf_2wq9tkz7hvbx4nmc8rde",
  "object": "pdf",
  "status": "completed",
  "url": "https://img.imageapis.com/i/pdf_2wq9tkz7hvbx4nmc8rde.pdf",
  "format": "pdf",
  "pages": 2,
  "bytes": 90412,
  "units": 2,
  "created": "2026-10-10T18:10:40Z",
  "completed": "2026-10-10T18:10:42Z",
  "expires": "2026-11-09T18:10:40Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/pdfs/pdf_2wq9tkz7hvbx4nmc8rde" \
  -H "X-API-Key: YOUR_KEY"
```

# Screenshots

# Screenshots

## POST /v1/screenshots

**Screenshot a public web page**

Loads the page in a real browser and captures the viewport, the full page, or one element. Private and local addresses are refused.

### Request body (application/json)

```json
{
  "url": "https://apidirectory.com/",
  "width": 1280,
  "height": 800,
  "full_page": false,
  "hide": [
    ".cookie-banner"
  ]
}
```

### Responses

- `200` With response=binary: the file itself, with X-Image-Id and X-Image-Url headers
- `201` Created

```json
{
  "id": "shot_9pxk3mz7dqwb2hnt4vce",
  "object": "screenshot",
  "status": "completed",
  "url": "https://img.imageapis.com/i/shot_9pxk3mz7dqwb2hnt4vce.png",
  "source_url": "https://apidirectory.com/",
  "final_url": "https://apidirectory.com/",
  "title": "APIDirectory",
  "http_status": 200,
  "format": "png",
  "width": 1280,
  "height": 800,
  "scale": 1,
  "bytes": 212044,
  "units": 1,
  "created": "2026-10-10T18:12:00Z",
  "completed": "2026-10-10T18:12:03Z",
  "expires": "2026-11-09T18:12:00Z"
}
```

- `202` Accepted: rendering in the background; the record has status pending and the webhook gets the finished one

```json
{
  "id": "shot_9pxk3mz7dqwb2hnt4vce",
  "object": "screenshot",
  "status": "completed",
  "url": "https://img.imageapis.com/i/shot_9pxk3mz7dqwb2hnt4vce.png",
  "source_url": "https://apidirectory.com/",
  "final_url": "https://apidirectory.com/",
  "title": "APIDirectory",
  "http_status": 200,
  "format": "png",
  "width": 1280,
  "height": 800,
  "scale": 1,
  "bytes": 212044,
  "units": 1,
  "created": "2026-10-10T18:12:00Z",
  "completed": "2026-10-10T18:12:03Z",
  "expires": "2026-11-09T18:12:00Z"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/screenshots" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://apidirectory.com/",
  "width": 1280,
  "height": 800,
  "full_page": false,
  "hide": [
    ".cookie-banner"
  ]
}'
```

## GET /v1/screenshots/{id}

**Fetch a screenshot's record**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The screenshot id Example: shot_9pxk3mz7dqwb2hnt4vce |

### Responses

- `200` OK

```json
{
  "id": "shot_9pxk3mz7dqwb2hnt4vce",
  "object": "screenshot",
  "status": "completed",
  "url": "https://img.imageapis.com/i/shot_9pxk3mz7dqwb2hnt4vce.png",
  "source_url": "https://apidirectory.com/",
  "final_url": "https://apidirectory.com/",
  "title": "APIDirectory",
  "http_status": 200,
  "format": "png",
  "width": 1280,
  "height": 800,
  "scale": 1,
  "bytes": 212044,
  "units": 1,
  "created": "2026-10-10T18:12:00Z",
  "completed": "2026-10-10T18:12:03Z",
  "expires": "2026-11-09T18:12:00Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl "https://api.imageapis.com/v1/screenshots/shot_9pxk3mz7dqwb2hnt4vce" \
  -H "X-API-Key: YOUR_KEY"
```

# Signed urls

# Signed bases

## GET /v1/signed-bases

**List this account's signed-URL bases**

### Responses

- `200` OK

```json
{
  "signed_bases": [
    {
      "id": "sb_8mz2kq7xvtnw4hbc3dpe",
      "object": "signed_base",
      "name": "Blog cards",
      "template": null,
      "secret": "sbs_1f2e3d4c5b6a79880011223344556677889900aabbccddeeff00112233445566",
      "url": "https://img.imageapis.com/s/sb_8mz2kq7xvtnw4hbc3dpe/{template}.png?{query}&sig={signature}",
      "how_to_sign": "signature = hex(HMAC-SHA256(secret, '/s/sb_8mz2kq7xvtnw4hbc3dpe/tpl_4nq8vzk2hdyw7bxme3rc.png?title=Hello&exp=1760000000')); append &sig=… to the same URL",
      "created": "2026-10-10T18:20:00Z"
    }
  ]
}
```

- `401` Missing or invalid API key (from the gateway)
- `429` Plan ceiling or rate limit reached; see X-Gw-Reset (from the gateway)

### Example

```bash
curl "https://api.imageapis.com/v1/signed-bases" \
  -H "X-API-Key: YOUR_KEY"
```

## POST /v1/signed-bases

**Create a signed-URL base: images that render on demand from a URL**

A signed base lets you build image URLs in your own code with no API call: `https://img.imageapis.com/s/<base>/<template>.png?title=…&sig=<hmac>`. The browser or crawler fetching the URL triggers the render; identical URLs are served from cache and cost nothing. Sign the path and query exactly as sent with HMAC-SHA256 and the base's secret, hex encoded. Add `exp` (unix seconds) to make a URL expire. Each new render costs one image against the key that created the base.

### Request body (application/json)

```json
{
  "name": "Blog cards"
}
```

### Responses

- `201` Created

```json
{
  "id": "sb_8mz2kq7xvtnw4hbc3dpe",
  "object": "signed_base",
  "name": "Blog cards",
  "template": null,
  "secret": "sbs_1f2e3d4c5b6a79880011223344556677889900aabbccddeeff00112233445566",
  "url": "https://img.imageapis.com/s/sb_8mz2kq7xvtnw4hbc3dpe/{template}.png?{query}&sig={signature}",
  "how_to_sign": "signature = hex(HMAC-SHA256(secret, '/s/sb_8mz2kq7xvtnw4hbc3dpe/tpl_4nq8vzk2hdyw7bxme3rc.png?title=Hello&exp=1760000000')); append &sig=… to the same URL",
  "created": "2026-10-10T18:20:00Z"
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl -X POST "https://api.imageapis.com/v1/signed-bases" \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Blog cards"
}'
```

## DELETE /v1/signed-bases/{id}

**Delete a signed-URL base; its URLs stop rendering**

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The base id Example: sb_8mz2kq7xvtnw4hbc3dpe |

### Responses

- `200` OK

```json
{
  "id": "sb_8mz2kq7xvtnw4hbc3dpe",
  "object": "signed_base",
  "deleted": true
}
```

- `401` Missing or invalid API key (from the gateway)
- `404` No such template or record on this account

```json
{
  "error": "string",
  "message": "string",
  "param": "string"
}
```

### Example

```bash
curl -X DELETE "https://api.imageapis.com/v1/signed-bases/sb_8mz2kq7xvtnw4hbc3dpe" \
  -H "X-API-Key: YOUR_KEY"
```

# Fonts

# Fonts

## GET /v1/fonts

**Fonts available to text layers**

Any Google Fonts family works by name; this list is the curated set with their weights. System fonts need no loading.

### Responses

- `200` OK

```json
{
  "fonts": [
    {
      "name": "Inter",
      "category": "sans-serif",
      "weights": "100..900"
    },
    {
      "name": "Playfair Display",
      "category": "serif",
      "weights": "400..900"
    }
  ],
  "system": [
    "Arial",
    "Georgia",
    "system-ui"
  ],
  "note": "Other Google Fonts families load at weight 400 when named"
}
```

- `401` Missing or invalid API key (from the gateway)
- `429` Plan ceiling or rate limit reached; see X-Gw-Reset (from the gateway)

### Example

```bash
curl "https://api.imageapis.com/v1/fonts" \
  -H "X-API-Key: YOUR_KEY"
```
