Sign in Get started

Credits

USD-denominated compute credits - balance, ledger history, per-operation usage, and pre-flight cost estimation.

View as Markdown

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 to 0. Read the *_micro_usd fields or *_usd properties 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_restricted before 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
Copied to clipboard