---
name: upload-image
description: Use this skill when you have an image (typically a Playwright screenshot from a QA or debugging session) that needs to be hosted at a public URL so it can be embedded in a GitHub issue, PR comment, or Slack message. Triggers on phrases like "include this screenshot in the issue", "attach this image", or after capturing a screenshot during automated testing.
---

# Upload image to banja-images

Hosts an image at a stable public URL via the banja-images API. Returns a URL you can drop into Markdown (`![](url)`) for GitHub issues, PRs, or Slack.

## Endpoint

`POST https://images.dev.banja.au/v1/images`

## Auth

Requires a bearer token in the `BANJA_IMAGES_KEY` environment variable. Ask the maintainer for one if you don't have it — do not commit it.

## Request

- `Content-Type: multipart/form-data`
- Form field name: `file` (required)
- Allowed types: `image/png`, `image/jpeg`, `image/webp`, `image/gif` (sniffed from bytes — `Content-Type` from the client is ignored)
- Max size: 10 MiB

```bash
curl -X POST https://images.dev.banja.au/v1/images \
  -H "Authorization: Bearer $BANJA_IMAGES_KEY" \
  -F "file=@./screenshot.png"
```

## Response (201)

```json
{
  "id": "0192f8a0-7c3e-7000-8000-000000000000",
  "url": "https://images.dev.banja.au/v1/images/0192f8a0-7c3e-7000-8000-000000000000",
  "mime": "image/png",
  "bytes": 84213,
  "uploadedAt": "2026-04-15T04:32:11.000Z"
}
```

Use the `url` directly in Markdown:

```markdown
![Failing test on /checkout](https://images.dev.banja.au/v1/images/0192f8a0-7c3e-7000-8000-000000000000)
```

URLs are immutable and cached for a year — never reused.

## Errors

All error responses are `application/problem+json` (RFC 7807):

| Status | Meaning |
|--------|---------|
| 400 | Missing `file` field, or invalid request |
| 401 | Missing/invalid bearer token |
| 413 | File exceeds 10 MiB |
| 415 | Not a recognised image, or SVG (not allowed — XSS risk) |

Example:

```json
{
  "type": "https://images.dev.banja.au/errors/unsupported-media-type",
  "title": "Unsupported Media Type",
  "status": 415,
  "detail": "Unsupported media type \"image/svg+xml\". Allowed: image/png, image/jpeg, image/webp, image/gif"
}
```

## Other operations

- `GET /v1/images/{id}` — fetch bytes (public, no auth)
- `GET /v1/images/{id}/metadata` — fetch JSON metadata (public)
- `DELETE /v1/images/{id}` — delete (auth required)

## Workflow for Playwright screenshots

After capturing a screenshot via the Playwright MCP, upload it before referencing in an issue:

1. Capture screenshot to a local path (e.g. `.playwright-mcp/foo.png`)
2. POST it to `/v1/images` per above
3. Use the returned `url` in the issue body — never reference the local path

Full reference: https://images.dev.banja.au/docs
