---
title: "Request a zap invoice for an image (wallet → creator)"
method: POST
path: "/v1/images/{id}/zap"
tags: ["Zaps"]
---

# Request a zap invoice for an image (wallet → creator)

`POST /v1/images/{id}/zap`

## Request

- Base URL: `https://api.memestack.ai`
- URL: `https://api.memestack.ai/v1/images/{id}/zap`
- Auth: one of:
  - none
  - HTTP bearer

Mints a bolt11 invoice from the RECIPIENT's own Lightning address — the uploader's `lightning_address`, or the platform's address for imported (system-uploaded) content — and answers a signed `ticket` the client redeems at POST /v1/zaps/redeem once the invoice is paid. MemeStack holds nothing: the sats go straight to the recipient's wallet, there is no fee and no balance, and nothing is written until settlement is proven. `attested` says whether the recipient's provider is one whose settlement proof counts (an unattested zap is recorded as a receipt for the creator and never enters the counters or rankings). Optional authentication: a logged-in payer is recorded on the zap and earns a streak; anonymous zaps are recorded under the anonymous system user. Rate limited 10/min/IP. Returns 404 while ZAPS_ENABLED is off.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `amount_sats` integer, required: Whole sats, 10–100,000.

## Response `200`

The zap offer (Cache-Control: private, no-store). Pay `invoice` before `invoice_expires_at`, then redeem `ticket` before `ticket_expires_at` (15 minutes).

- object
  - `ticket` string: Signed zap ticket — the only thing the server remembers between offer and redeem.
  - `invoice` string: bolt11 invoice for exactly `amount_sats`, payable to the recipient.
  - `amount_sats` integer
  - `invoice_expires_at` string, date-time
  - `ticket_expires_at` string, date-time
  - `verify_supported` boolean: True when the recipient's provider implements LUD-21 verify, so the redeem can confirm payment without a preimage.
  - `attested` boolean
  - `recipient` object
    - `kind` 'uploader' | 'platform'
    - `display_name` string, nullable
    - `source` string, nullable: For a platform recipient, where the content was imported from (e.g. "Our World in Data").
    - `domain` string: The Lightning-address domain the invoice was minted from.

## Other responses

- `400`: Amount not a whole number in 10–100,000 (INVALID_AMOUNT), or the caller owns the image (SELF_ZAP).
- `404`: Image not found (IMAGE_NOT_FOUND), or zaps are disabled (ZAPS_ENABLED off).
- `409`: The uploader has not set a Lightning address (NO_LIGHTNING_ADDRESS); body carries `uploader_display_name`. The uploader is nudged at most once per interval.
- `429`: Rate limit exceeded (10/min/IP).
- `503`: PAYMENT_UNAVAILABLE — the recipient's provider could not mint an invoice, or the ticket signer is unconfigured.

---

[API](https://skmtc.dev/memestack/apis/memestack-api.md) · [All operations](https://skmtc.dev/memestack/apis/memestack-api/llms.txt) · [OpenAPI document](https://skmtc.dev/memestack/apis/memestack-api/revisions/9d3a19565f75?raw)
