Credits
USD-denominated compute credits - balance, ledger history, per-operation usage, and pre-flight cost estimation.
Pictograph bills paid operations against a USD-denominated compute-credit wallet, one per organization. Free actions (uploads, exports, search, manual annotation) cost nothing.
Units. Credits travel on the wire as integer micro-USD (µUSD):
1 USD = 1,000,000 µUSD. Every *_micro_usd field is an int; the SDK models expose
matching *_usd float properties for display.
Allowance plus pay-as-you-go. Each plan includes a monthly allowance (Free $5, Core $29, Pro $50, Team $100) that renews per billing period and does not roll over. Past the allowance, an organization with a saved card can enable pay-as-you-go in the app; prepaid compute does carry over. With it off, the organization hard-stops at its allowance. An optional monthly Budget cap bounds spend beyond the allowance.
balance
Current wallet state plus the last 20 ledger entries.
Source: Credits.balance
balance = client.credits.balance()
print(f"{balance.remaining_usd:.2f} of {balance.allowance_usd:.2f} included left")
print(f"Spent this period: ${balance.spend_usd:.2f}")
print(f"Overage: ${balance.overage_usd:.2f} (budget cap ${balance.budget_usd:.2f})")
print("Allowance resets:", balance.credits_reset_at)
pictograph credits balance
curl -s "https://api.pictograph.io/api/v1/developer/credits/balance" \
-H "X-API-Key: $PICTOGRAPH_API_KEY"
Returns CreditBalance
CreditBalance · 11 fields
class CreditBalance(BaseModel):
"""Current compute-credit state for an organization (USD, stored as µUSD)."""
included_allowance_micro_usd: int = 0
included_remaining_micro_usd: int = 0
budget_micro_usd: int = 0
period_spend_micro_usd: int = 0
period_overage_micro_usd: int = 0
budget_remaining_micro_usd: int = 0
period_start: datetime | None = None
credits_reset_at: datetime | None = None
credits_remaining: int = 0
credits_monthly_allowance: int = 0
recent_history: list[CreditLedgerEntry] = []
The authoritative fields are integer micro-USD:
| Field | Meaning |
|---|---|
included_allowance_micro_usd |
Monthly included allowance |
included_remaining_micro_usd |
Allowance left this period |
budget_micro_usd |
Overage cap beyond the allowance. Equals the allowance when pay-as-you-go is off. |
period_spend_micro_usd |
Total compute spend this period |
period_overage_micro_usd |
Spend beyond the included allowance |
budget_remaining_micro_usd |
Remaining overage budget under the cap |
period_start / credits_reset_at |
Start of the current period, and when the allowance next resets |
Each has a float-dollar property: .allowance_usd, .remaining_usd, .budget_usd,
.spend_usd, .overage_usd, .budget_remaining_usd.
The whole-dollar integer fields (
credits_remaining,credits_monthly_allowance) are deprecated, kept for backward compatibility and defaulting to0. Read the*_micro_usdfields or*_usdproperties instead.
history
One page of the ledger, newest first.
Source: Credits.history
| Arg | Type | Default | Notes |
|---|---|---|---|
limit |
int |
50 |
Page size (server cap: 100) |
offset |
int |
0 |
Page offset |
for entry in client.credits.history(limit=50, offset=0):
direction = "debit" if entry.amount < 0 else "credit"
print(entry.created_at, direction, abs(entry.amount), "µUSD", entry.operation)
pictograph credits history --limit 50 --offset 0
curl -s "https://api.pictograph.io/api/v1/developer/credits/history?limit=50&offset=0" \
-H "X-API-Key: $PICTOGRAPH_API_KEY"
Returns list[CreditLedgerEntry]
CreditLedgerEntry · 7 fields
class CreditLedgerEntry(BaseModel):
"""A single entry in the organization's credit ledger."""
id: str
operation: str
amount: int
balance_after: int | None = None
description: str | None = None
metadata: dict[str, Any] | None = None
created_at: datetime
amount and balance_after are signed µUSD integers. amount < 0 is a debit;
amount > 0 is a credit or refund (top-up, monthly reset, training overcharge
refund). balance_after is the spendable balance immediately after the entry posted.
iter
Auto-paging iterator over the entire ledger.
Source: Credits.iter
| Arg | Type | Default | Notes |
|---|---|---|---|
page_size |
int |
100 |
Rows fetched per underlying request. Tuning only - the iterator yields every item either way. |
max_total |
int | None |
None |
Stop after this many items. None walks everything. |
for entry in client.credits.iter(page_size=100):
print(entry.balance_after, entry.operation)
pictograph credits history --all --max-total 5000
# REST pages manually: raise offset until fewer than `limit` rows come back.
curl -s "https://api.pictograph.io/api/v1/developer/credits/history?limit=100&offset=0" \
-H "X-API-Key: $PICTOGRAPH_API_KEY"
Returns OffsetPager[CreditLedgerEntry]
CreditLedgerEntry · 7 fields
class CreditLedgerEntry(BaseModel):
"""A single entry in the organization's credit ledger."""
id: str
operation: str
amount: int
balance_after: int | None = None
description: str | None = None
metadata: dict[str, Any] | None = None
created_at: datetime
usage_by_operation
Per-operation spend (debits only), aggregated server-side over a rolling window. Use it for a “where did my credits go” breakdown without paging the raw ledger.
Source: Credits.usage_by_operation
| Arg | Type | Default | Notes |
|---|---|---|---|
range |
str |
"month" |
day / week / month / all |
usage = client.credits.usage_by_operation(
range="month",
)
for op in usage.operations:
print(f"{op.operation}: ${op.total_usd:.2f} over {op.event_count} events")
pictograph credits usage --range month
curl -s "https://api.pictograph.io/api/v1/developer/credits/usage-by-operation?range=month" \
-H "X-API-Key: $PICTOGRAPH_API_KEY"
Returns UsageByOperation
UsageByOperation · 5 fields
class UsageByOperation(BaseModel):
"""Per-operation compute-spend breakdown over a rolling window."""
range: str
since: str | None = None
operations: list[OperationUsage] = []
total_micro_usd: int = 0
total_events: int = 0
estimate
Pre-flight cost check before invoking a paid operation. Prices are set server-side, so
estimate always returns the live price and you never hard-code a cost.
Source: Credits.estimate
| Arg | Type | Default | Notes |
|---|---|---|---|
operation |
str |
required | Operation slug, e.g. "training_a10g" |
quantity |
int |
1 |
Units to price |
estimate = client.credits.estimate(
operation="training_a10g",
quantity=30,
)
print(f"${estimate.per_unit_usd:.4f} per {estimate.unit}")
print(f"Total ${estimate.total_usd:.2f}, sufficient: {estimate.sufficient}")
pictograph credits estimate training_a10g --quantity 30
curl -s "https://api.pictograph.io/api/v1/developer/credits/estimate?operation=training_a10g&quantity=30" \
-H "X-API-Key: $PICTOGRAPH_API_KEY"
Returns CreditEstimate
CreditEstimate · 11 fields
class CreditEstimate(BaseModel):
"""Estimated cost of a planned operation (USD, stored as µUSD), plus an affordability check."""
operation: str
unit: str
quantity: int
micro_usd_per_unit: int = 0
total_micro_usd: int = 0
remaining_micro_usd: int = 0
sufficient: bool = False
credits_per_unit: int = 0
total_credits: int = 0
minimum: int = 0
credits_remaining: int = 0
The total_usd / per_unit_usd / remaining_usd properties are the float-dollar views.
Common slugs: training_a10g, training_a100, training_h100,
sam3_auto_annotation, inference_t4, image_generate_imagen_fast,
image_edit_gemini_flash.
sufficient=True is not a guarantee: another caller can drain the wallet between the
estimate and the call. The authoritative answer is the operation’s own
PaymentRequiredError.
Tier-gated operations. Image generation and editing, batch auto-annotation, model training, and model deployments require the Core plan or higher. SAM3 auto-annotation is available on every tier. On a Free-tier organization the gated endpoints return
403 tier_restrictedbefore any credit is debited.
Gating a paid step
Check the estimate, then commit:
estimate = client.credits.estimate(
operation="training_a10g",
quantity=30,
)
if not estimate.sufficient:
raise SystemExit(f"Need ${estimate.total_usd:.2f}, have ${estimate.remaining_usd:.2f}")
run = client.training.create(
dataset_name="road-signs",
export_name="road-signs-v1",
pipeline_type="yolox",
name="road-signs-detector",
)
Auto-annotation has an exact quote rather than an estimate, and can price images you
have not uploaded yet. See
auto_annotate.quote.
PaymentRequiredError
Raised when an operation’s cost exceeds the spendable balance, that is the included allowance plus any remaining overage budget. Raising the plan or the Budget cap clears it.
from pictograph.exceptions import PaymentRequiredError
try:
client.training.create(
dataset_name="road-signs",
export_name="road-signs-v1",
pipeline_type="yolox",
name="road-signs-detector",
)
except PaymentRequiredError as exc:
# credit_cost / credits_remaining are integer µUSD (exc.unit == "micro_usd")
print(f"Need ${exc.credit_cost / 1e6:.2f}, have ${exc.credits_remaining / 1e6:.2f}")
print("Top up at:", exc.upgrade_url)
Refunds
Training auto-refunds unused GPU minutes when a run is cancelled mid-training, or
fails before consuming its full timeout budget. Refunds appear as positive ledger
entries with operation training_refund_<gpu>. No SDK call is needed.
Common errors
| Status | Exception | Cause |
|---|---|---|
| 402 | PaymentRequiredError |
Raised by the operation being estimated, never by estimate itself |
| 422 | ValidationError |
operation is not a known credit operation slug |