Credits
Balance, ledger history, and pre-flight cost estimation. Gate paid operations to avoid mid-run PaymentRequiredError.
Pictograph uses a credit ledger (signed integers, per organization) for paid operations. Free actions (uploads, exports, search) cost 0.
from pictograph import Client
client = Client()
balance
Current balance + monthly allowance + last 20 ledger entries.
balance = client.credits.balance()
print(balance.credits_remaining, "/", balance.credits_monthly_allowance)
print("Resets:", balance.credits_reset_at)
for entry in balance.recent_history:
print(entry.created_at, entry.operation, entry.amount)
Returns CreditBalance.
history
Page through the credit ledger (newest first).
entries = client.credits.history(limit=50, offset=0)
for e in entries:
direction = "debit" if e.amount < 0 else "credit"
print(e.created_at, direction, abs(e.amount), e.operation)
Sign convention: amount < 0 = debit (operation consumed credits),
amount > 0 = credit / refund (top-up, training overcharge refund).
iter
Auto-paging iterator over the entire ledger.
for entry in client.credits.iter(page_size=100):
print(entry.balance_after, entry.operation)
estimate
Pre-flight cost check before invoking a paid operation.
estimate = client.credits.estimate("training_a10g_per_minute", quantity=30)
print(estimate.total_credits, "credits;", "sufficient:", estimate.sufficient)
sufficient=True is not a guarantee — another caller may drain credits
between the estimate and the actual call. The authoritative answer is
the operation’s own PaymentRequiredError.
Cost cheatsheet
| Operation slug | Approx cost |
|---|---|
sam3_per_minute | 3 cr session minimum + ~1/prompt |
training_a10g_per_minute | 10 cr/min |
training_a100_per_minute | 60 cr/min |
training_h100_per_minute | 120 cr/min |
image_generate_imagen_fast | 5 cr/image |
image_edit_gemini_flash | 3 cr/image |
image_inference | 1 cr/image |
The full table lives server-side in utils.tier_limits.CREDIT_COSTS.
Gating in workflows
full_pipeline already gates on credit balance before kicking off
paid phases:
from pictograph.workflows import full_pipeline
report = full_pipeline(
client,
dataset_name="…", folder="…", classes=…, pipeline="yolox",
min_credits=1, # skip annotate + train if balance < 1
)
if report.credit_skip_reason:
print(report.credit_skip_reason)
min_credits=None disables the check.
PaymentRequiredError details
from pictograph.exceptions import PaymentRequiredError
try:
client.training.create(dataset_name, export_name, pipeline_type="yolox")
except PaymentRequiredError as e:
print(f"Need {e.required}, have {e.remaining}")
print(f"Top up at: {e.upgrade_url}")
Refunds
The training pipeline auto-refunds unused GPU minutes when:
- A run is cancelled mid-training.
- A run failed before consuming the full
timeoutbudget.
Refunds appear as positive ledger entries with operation
training_refund_<gpu>. No SDK call required.
Common errors
| Status | Exception | Cause |
|---|---|---|
| 422 | ValidationError | operation slug not in the cost table |
| 402 | PaymentRequiredError | (raised by the operation being estimated, not by estimate itself) |