Windpaint
Get started

Pricing

How Windpaint bills: prepaid credits, a fixed price per output, holds that are released on failure, estimates, top-ups, and a worked example.

Windpaint bills in prepaid credits. Every output has a fixed price in credits that depends on the model and the tier you ask for (resolution, and duration for video). You see the price before you submit, it’s held while the job runs, and you’re charged only if the job completes.

Credits

One credit costs $0.05 when you buy it. Credits belong to the organization, and every project and member spends from the same balance.

Current prices

These are the prices at the time of writing. Prices can change, so read them from the API rather than hard-coding them (see below).

CapabilityModelTierCreditsUSD
image.generatez-image-turbo1k (1024 px long edge)0.08 per image$0.004
image.generatez-image-turbo2k (2048 px long edge)0.3 per image$0.015
video.generatewan-2.2-i2v480p, 5 s4 per clip$0.20

Each request makes one image or one clip. Aspect ratio doesn’t change the price. Uploads, downloads, storage, and API calls that only read data are free.

GET /v1/generation/capabilities is the authoritative price list. Each model under each capability carries a prices array with one row per tier:

curl
curl https://api.windpaint.ai/v1/generation/capabilities \
  -H "Authorization: Bearer $WINDPAINT_API_KEY" \
  | jq '.data[] | {capability: .id, models: [.models[] | {model, prices}]}'
{
  "capability": "image.generate",
  "models": [
    {
      "model": "z-image-turbo",
      "prices": [
        { "resolution": "1k", "duration_s": null, "credits": "0.08" },
        { "resolution": "2k", "duration_s": null, "credits": "0.3" }
      ]
    }
  ]
}

Credit amounts are always strings in the API, to keep them exact.

Holds: you pay only for completed jobs

  1. Submit. The job’s price is fixed and returned as credits_estimate. That amount is held from your available balance. If the organization doesn’t have enough available credit, the submit fails with 402 billing.insufficient_credits, and details tells you required and available.
  2. Complete. The hold is captured and becomes a charge. credits.actual on the job equals the estimate.
  3. Fail, nsfw, or cancel. The hold is released in full. You’re not charged for jobs that don’t produce an output.

While a job runs, its credits show as held on your balance and aren’t part of available. A price change after you submit doesn’t affect jobs already submitted.

Products work a little differently: starting a run checks your balance against the run’s total estimate but doesn’t reserve it. Each step holds its own credits when it starts, so a run can fail partway if your balance runs out in the meantime. Steps that already completed stay charged.

Estimate before you submit

POST /v1/generation/estimate takes the same body you’d submit, plus capability, and returns the price and output size without creating a job:

curl
curl https://api.windpaint.ai/v1/generation/estimate \
  -H "Authorization: Bearer $WINDPAINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capability": "image.generate", "prompt": "a red bicycle", "resolution": "2k", "aspect_ratio": "16:9"}'
{
  "data": {
    "capability": "image.generate",
    "model": "z-image-turbo",
    "credits": "0.3",
    "width": 2048,
    "height": 1152,
    "available": true
  }
}

credits is null and available is false when that model and tier can’t be run right now; submitting it would fail. The CLI’s estimate also prints your current balance. For a product, use POST /v1/workflows/products/{slug}/estimate (see Products).

Getting credits

Free credits on signup. When your early-access account is approved, your organization gets 200 credits. They expire 30 days after they’re granted.

Top-ups. Buy credits in the dashboard under Settings → Billing → Buy. Pick a preset (500, 1,000, 2,500, or 5,000 credits) or enter an amount between 100 credits (5)and100,000credits(5) and 100,000 credits (5,000). Payment goes through Stripe Checkout, and Stripe emails you the receipt. Purchased credits expire 365 days after purchase.

You can also start a top-up from the API. It returns a Checkout URL to open in a browser:

curl https://api.windpaint.ai/v1/billing/topups \
  -H "Authorization: Bearer $WINDPAINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"credits": 1000}'

GET /v1/billing/topups/quote returns the current price per credit, the minimum and maximum, and the expiry period.

Spend order. Credits are spent from the batch that expires soonest first, then from the oldest. In practice that means free signup credits are used before purchased ones.

Low-balance alert. Set a threshold under Settings → Billing or with PUT /v1/billing/settings ({"low_balance_threshold": 50}; null turns it off). When your available balance drops below it, org admins get an email and the billing.credits_low webhook event fires. It fires once, and again only after the balance has gone back above the threshold.

Check your balance with windpaint balance or GET /v1/billing/balance, which returns available, held, a breakdown by source, and when the next credits expire. See Billing for the ledger, holds, and usage.

What’s not available

  • No subscriptions or monthly plans. Credits are prepaid only.
  • No invoices. Each top-up gets a Stripe receipt by email.
  • No auto top-up. When credits run out, new jobs fail with 402 until you buy more.
  • No spending limits or per-project budgets. Any key with permission to generate can spend the organization’s whole balance. Use the low-balance alert and key roles to keep an eye on it.

Worked example

Say you generate 50 draft images at 1k, pick 5 and re-render them at 2k, and animate 3 of those into clips. One of the clips fails and you resubmit it.

ItemCountCredits eachCredits
image.generate at 1k500.084.0
image.generate at 2k50.31.5
video.generate at 480p, 5 s (completed)3412.0
video.generate (failed, released)100
Total17.5

17.5 credits is $0.875 at the top-up rate, and fits inside the free signup credits several times over.