Getting Started
Quickstart
Add Wind billing to your AI app in about 15 minutes.
Create your app and get an API key
In the Dashboard, create a new app. Go to the General tab to generate a key — it starts with sk_live_.
Then go to the Features tab and create a feature with an ID (e.g. chat) and a pricing mode:
per_call Fixed price per request — e.g. $0.10 every time. per_token Cost-based markup — e.g. 1.3× provider cost. feature_id in every request must exactly match a feature you've created, or calls fail with NO_PRICING_RULE.
Connect a user's Wind wallet
Users connect their Wind wallet once using trywind. After that, all AI requests bill their wallet automatically.
npm install trywind wind-ai
const wind = new WindManager({ appId: 'YOUR_APP_ID', appName: 'Your App' })
// When the user clicks "Connect Wind wallet"
wind.connect({ externalUserId: currentUser.id })
After the redirect back, call parseReturnUrl() on page load:
const result = wind.parseReturnUrl()
if (result?.connected) {
await fetch('/api/me/wind-connect', {
method: 'POST',
body: JSON.stringify({ windUserId: result.windUserId }),
})
}
Store windUserId on the user row in your DB.
Make a billable AI request
On your server, initialize the wind-ai client and call client.chat(). Wind handles billing automatically.
import { createClient } from 'wind-ai'
const client = createClient({
apiKey: process.env.WIND_API_KEY,
baseUrl: 'https://wind-production-3225.up.railway.app',
})
const response = await client.chat({
userId: user.windUserId,
featureId: 'chat',
model: 'google/gemini-2.5-flash',
messages: [{ role: 'user', content: userMessage }],
}) Parse the response
The response follows the OpenAI chat completion shape with a receipt field added by Wind.
// The AI reply
const text = response.choices[0].message.content
// Billing receipt
const {
user_charge_cents, // credits deducted from the user's wallet
provider_cost_cents, // what Wind paid the model provider
dev_share_cents, // your earnings on this request
input_tokens,
output_tokens,
} = response.receipt Show the user their wallet balance
const res = await fetch(`https://wind-production-3225.up.railway.app/v1/user/status?userId=${user.windUserId}`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const { wallet } = await res.json()
// wallet.availableCents — spendable balance in cents
// wallet.balanceCents — total (before holds) Handle low balance gracefully
When a request fails with INSUFFICIENT_FUNDS, send the user to Wind to top up:
try {
const result = await callYourBackend(message)
displayResult(result)
} catch (err) {
if (err.message === 'low_balance') {
window.open('https://user.usewind.app/wallet', '_blank')
showToast('Top up your Wind wallet to continue.')
}
} force_auth=true.