Overview

Oh My Ghost is an API-first SVG icon generation service. Send a style name and optional brand context, and receive a unique, AI-generated SVG ghost icon in seconds.

Base URL

https://x402-logo-psz3ydh6d-desplega-ai.vercel.app

All API endpoints below are relative to this base URL. Example: https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/styles

Content Type

All POST requests must include Content-Type: application/json. All responses are JSON.

How It Works

  1. Browse stylesGET /api/styles returns all available ghost styles.
  2. Generate an icon POST /api/generate starts an async job. Requires x402 payment ($0.10). Returns a jobId.
  3. Poll for completion GET /api/generate/[jobId]/status until status is "completed". Response includes the svg and a permanent access token.
  4. Retrieve later GET /api/asset/[token] fetches the SVG at any time.
  5. Rate the result — Optionally POST /api/rate to submit feedback.

Pricing

$0.10 per image (SVG & PNG). Payment is handled via the x402 micropayment protocol — no API keys, no accounts, no subscriptions. Only POST /api/generate requires payment. All other endpoints are free.

x402 Payment Protocol

The /api/generate endpoint uses the x402 micropayment protocol for payment. Here's how it works:

  1. Call the endpoint — Send your POST request normally with your JSON body.
  2. Receive a 402 — The server responds with HTTP 402 Payment Required and a JSON body describing accepted payment methods (network, price, recipient address).
  3. Make the payment — Transfer the exact amount on the specified EVM network to the payTo address.
  4. Retry with proof — Re-send the same request with an X-PAYMENT header containing the base64-encoded payment receipt.
  5. Receive the response — The server verifies payment via the x402 facilitator and processes your request.
402 response body
{
  "accepts": [
    {
      "scheme": "exact",
      "price": "$0.10",
      "network": "eip155:84532",
      "payTo": "0x..."
    }
  ],
  "description": "Generate a custom SVG icon in your chosen style",
  "mimeType": "application/json"
}

Using an x402 client library (recommended)

The easiest approach is to use an x402 client library that handles the 402 → payment → retry flow automatically:

JavaScript (@x402/client)
import { withX402Payment } from "@x402/client";

// Wrap fetch with x402 payment handling
const x402Fetch = withX402Payment(fetch, { wallet });

// Use it exactly like regular fetch — payment happens automatically
const res = await x402Fetch("https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/generate", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ styleName: "classic" }),
});

const { jobId } = await res.json();

Manual x402 flow (for agents without a library)

Step-by-step manual flow
# 1. Send the request — you'll get a 402
curl -s -w "\nHTTP_STATUS:%{http_code}" \
  -X POST https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/generate \
  -H "Content-Type: application/json" \
  -d '{"styleName": "classic"}'
# → HTTP 402 with payment instructions in body

# 2. Parse the 402 body to get: scheme, price, network, payTo
# 3. Make an EVM payment for $0.10 to the payTo address on the specified network
# 4. Retry with the X-PAYMENT header containing base64-encoded payment proof:

curl -X POST https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/generate \
  -H "Content-Type: application/json" \
  -H "X-PAYMENT: <base64-encoded-payment-receipt>" \
  -d '{"styleName": "classic"}'
# → HTTP 200 with { jobId, runId, status: "pending" }

Quick Example (full flow)

Generate a ghost icon end-to-end
# Assumes x402 payment is handled by your client

# 1. List available styles
curl -s https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/styles | jq '.styles[].name'

# 2. Generate an icon
RESPONSE=$(curl -s -X POST https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/generate \
  -H "Content-Type: application/json" \
  -d '{"styleName": "classic", "brandName": "Acme Corp"}')
JOB_ID=$(echo $RESPONSE | jq -r '.jobId')

# 3. Poll until complete (typically 5-15 seconds)
while true; do
  STATUS=$(curl -s "https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/generate/$JOB_ID/status")
  STATE=$(echo $STATUS | jq -r '.status')

  if [ "$STATE" = "completed" ]; then
    TOKEN=$(echo $STATUS | jq -r '.token')
    echo "$STATUS" | jq -r '.svg' > ghost.svg
    echo "Done! Token: $TOKEN"
    break
  elif [ "$STATE" = "failed" ]; then
    echo "Failed: $(echo $STATUS | jq -r '.error')"
    exit 1
  fi
  sleep 2
done

# 4. Retrieve the asset later by token
curl -s "https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/asset/$TOKEN" | jq .

# 5. Rate the result (optional)
curl -s -X POST https://x402-logo-psz3ydh6d-desplega-ai.vercel.app/api/rate \
  -H "Content-Type: application/json" \
  -d "{
    \"token\": \"$TOKEN\",
    \"rating\": 5,
    \"styleName\": \"classic\"
  }"