curl --request GET \
--url https://api.vaquill.ai/api/v1/credits/balance \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/credits/balance"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/credits/balance', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/credits/balance"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"creditsRemaining": 103039,
"usdRemaining": 1030.39,
"bySource": [
{
"source": "comp",
"credits": 20000
},
{
"source": "payg",
"credits": 64699
},
{
"source": "subscription",
"credits": 18340
}
],
"nextExpiry": {
"at": "2026-10-12T13:56:31Z",
"credits": 18340
},
"plan": "business",
"totalPurchased": 143960,
"totalConsumed": 48471,
"rateLimit": {
"perMinute": 150,
"perHour": 2500,
"perDay": 10000
},
"asOf": "2026-09-19T12:34:56Z"
}{
"detail": "Invalid token"
}{
"detail": "Rate limit exceeded. Try again in 42 seconds."
}Get your credit balance
Returns the credits this API key’s account can spend right now.
Free. This endpoint is never charged, so you can poll it to drive alerting or a pre-flight check without the check itself costing you anything. It is rate limited like every other key-authenticated route.
Authentication: any valid vq_key_ key. No particular scope is required.
What the number means
creditsRemaining is derived from your live credit buckets under the same
expiry rule the billing path applies, so it is what a call would actually be
allowed to spend, not a cached figure that a nightly job later corrects.
It is the same field name metered responses use, so you can read creditsRemaining
the same way everywhere.
Not all credits behave alike
Read bySource before assuming a balance is durable. subscription credits are
use-it-or-lose-it and are forfeited at the end of the period, while payg
credits you purchased burn last and persist. nextExpiry tells you what is
about to be forfeited and when, which is the one thing a balance alone cannot.
Two separate ceilings
Credits are how MUCH you may spend; rateLimit is how FAST you may call. They
are independent, so a healthy balance does not exempt you from throttling and
staying under the rate limit does not pay for a call.
rateLimit has your plan applied and lets you size a client before issuing a
request. Every response also carries X-RateLimit-Limit, X-RateLimit-Remaining
and X-RateLimit-Reset for the per-minute window, plus X-RateLimit-Limit-Day
and X-RateLimit-Remaining-Day for the daily backstop; those report the same
ceilings with your live headroom.
Example
curl https://api.vaquill.ai/api/v1/credits/balance \
-H "Authorization: Bearer $VAQUILL_API_KEY"
{
"creditsRemaining": 103039.0,
"usdRemaining": 1030.39,
"bySource": [
{ "source": "payg", "credits": 102539.0 },
{ "source": "subscription", "credits": 500.0 }
],
"nextExpiry": { "at": "2026-10-01T00:00:00Z", "credits": 500.0 },
"plan": "business",
"totalPurchased": 150000.0,
"totalConsumed": 46961.0,
"asOf": "2026-09-19T12:34:56Z"
}
curl --request GET \
--url https://api.vaquill.ai/api/v1/credits/balance \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.vaquill.ai/api/v1/credits/balance"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.vaquill.ai/api/v1/credits/balance', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.vaquill.ai/api/v1/credits/balance"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"creditsRemaining": 103039,
"usdRemaining": 1030.39,
"bySource": [
{
"source": "comp",
"credits": 20000
},
{
"source": "payg",
"credits": 64699
},
{
"source": "subscription",
"credits": 18340
}
],
"nextExpiry": {
"at": "2026-10-12T13:56:31Z",
"credits": 18340
},
"plan": "business",
"totalPurchased": 143960,
"totalConsumed": 48471,
"rateLimit": {
"perMinute": 150,
"perHour": 2500,
"perDay": 10000
},
"asOf": "2026-09-19T12:34:56Z"
}{
"detail": "Invalid token"
}{
"detail": "Rate limit exceeded. Try again in 42 seconds."
}Authorizations
API key issued from the developer dashboard. Pass as Authorization: Bearer vq_key_...
Response
Current spendable balance for the calling key's account.
Spendable credit balance for the calling API key's account.
Credits you can actually spend right now. Deliberately the same field name that metered responses return, so one name means one thing across the API.
Derived from your live credit buckets under the same expiry rule the billing path applies, so it never promises credits a call would refuse to spend.
103039
creditsRemaining in USD, at the published conversion rate (1 credit = $0.01). Provided so you do not have to hardcode the rate; GET /api/v1/api-credits/pricing is its source of truth.
1030.39
Lifetime credits added to this account.
150000
Lifetime credits spent by this account.
46961
When this balance was computed. The value is live, not cached, so this is the instant the buckets were read.
creditsRemaining split by funding source, and it always sums to it. Worth reading because the sources do not behave alike: subscription credits are use-it-or-lose-it at the period end, while payg credits you bought are durable and burn last.
Show child attributes
Show child attributes
The soonest expiry across your credits, or null if none of them expire. Poll this to avoid silently forfeiting an allowance.
Show child attributes
Show child attributes
Active API subscription tier, or null on pay-as-you-go. Also determines your rate-limit multiplier. Briefly cached, so a subscription change made seconds ago may not be reflected yet; creditsRemaining is always live.
"business"
How fast this key may call, as opposed to how much it may spend. The two ceilings are independent: holding credits does not exempt you from these, and staying under these does not pay for a call.
These are the ceilings themselves, with your plan already applied, so you can size a client BEFORE issuing a request. The X-RateLimit-* headers on every response report the same ceilings plus your live headroom, and the two agree.
Show child attributes
Show child attributes
Was this page helpful?

