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.appAll 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
- Browse styles —
GET /api/stylesreturns all available ghost styles. - Generate an icon —
POST /api/generatestarts an async job. Requires x402 payment ($0.10). Returns ajobId. - Poll for completion —
GET /api/generate/[jobId]/statusuntil status is"completed". Response includes thesvgand a permanent accesstoken. - Retrieve later —
GET /api/asset/[token]fetches the SVG at any time. - Rate the result — Optionally
POST /api/rateto 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:
- Call the endpoint — Send your
POSTrequest normally with your JSON body. - Receive a 402 — The server responds with HTTP
402 Payment Requiredand a JSON body describing accepted payment methods (network, price, recipient address). - Make the payment — Transfer the exact amount on the specified EVM network to the
payToaddress. - Retry with proof — Re-send the same request with an
X-PAYMENTheader containing the base64-encoded payment receipt. - Receive the response — The server verifies payment via the x402 facilitator and processes your request.
{
"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:
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)
# 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)
# 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\"
}"