Sign in Get started

Credits

USD-denominated compute credits — balance, ledger history, budget/overage, and pre-flight cost estimation. Gate paid operations to avoid mid-run PaymentRequiredError.

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.

Every example below shows the Python SDK call and the equivalent raw REST request. The REST examples authenticate with an X-API-Key header; set PICTOGRAPH_API_KEY in your shell to copy-and-run them.

Units. Compute credits are carried on the wire as integer micro-USD (µUSD): 1 USD = 1,000,000 µUSD. Every *_micro_usd field is an int count of µUSD. The SDK models also expose *_usd convenience properties that divide by 1,000,000 to give a float dollar amount for display.

Allowance + pay-as-you-go. Each plan includes a monthly compute allowance (Free includes $5, Core $29, Pro $50, Team $100). The allowance renews at the start of every billing period and does not roll over. Beyond the included allowance, an org with a saved card can turn on pay-as-you-go in the app — either auto-recharge (top up the compute balance from the card when it runs low, by an amount you choose) or buying credits on demand. Pay-as-you-go is available on every plan including Free, and prepaid compute carries over between periods. With pay-as-you-go off, an org hard-stops at its included allowance (the Free tier stops at its included $5). An optional monthly Budget cap bounds total spend beyond the allowance — the fields below expose the allowance, the spend so far, and any Budget cap.

from pictograph import Client
client = Client()  # reads PICTOGRAPH_API_KEY

balance

Current wallet state + the last 20 ledger entries.

balance = client.credits.balance()

# USD convenience properties for display
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 so far: ${balance.overage_usd:.2f} (budget cap ${balance.budget_usd:.2f})")
print("Allowance resets:", balance.credits_reset_at)

for entry in balance.recent_history:
    print(entry.created_at, entry.operation, entry.amount)  # amount is signed µUSD
curl -s "https://api.pictograph.io/api/v1/developer/credits/balance" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns CreditBalance. The authoritative fields are integer micro-USD:

FieldMeaning
included_allowance_micro_usdMonthly included compute allowance (µUSD).
included_remaining_micro_usdIncluded allowance left this period (µUSD).
budget_micro_usdOverage budget cap beyond the allowance (µUSD). Equals the allowance when pay-as-you-go is off.
period_spend_micro_usdTotal compute spend this period (µUSD).
period_overage_micro_usdSpend beyond the included allowance this period (µUSD).
budget_remaining_micro_usdRemaining overage budget under the cap (µUSD).
period_startStart of the current billing period.
credits_reset_atWhen the monthly allowance resets next.

Each has a matching *_usd float property (.remaining_usd, .allowance_usd, .budget_usd, .overage_usd, .spend_usd, .budget_remaining_usd).

The whole-dollar integer fields (credits_remaining, credits_monthly_allowance) are deprecated — kept for backward compatibility, default 0. Read the *_micro_usd fields / *_usd properties instead.

history

Page through the ledger (newest first).

ArgTypeDefaultNotes
limitint50Page size (backend cap: 100)
offsetint0Page offset
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), "µUSD", e.operation)
curl -s "https://api.pictograph.io/api/v1/developer/credits/history?limit=50&offset=0" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Each entry’s amount and balance_after are signed micro-USD integers. Sign convention: amount < 0 = debit (operation consumed credit), amount > 0 = credit / refund (top-up, monthly reset, training-overcharge refund). balance_after is the org’s spendable balance (µUSD) immediately after the entry posted.

usage_by_operation

Per-operation compute spend (µUSD, debits only), aggregated in the database over a time window. Use this for a “where did my credits go” breakdown without paging the raw ledger.

ArgTypeDefaultNotes
rangestr"month"One of day / week / month / all
usage = client.credits.usage_by_operation(range="month")

print(f"{usage.total_events} events, ${usage.total_micro_usd / 1e6:.2f} total")
for op in usage.operations:
    print(f"{op.operation}: ${op.total_usd:.2f} over {op.event_count} events")
curl -s "https://api.pictograph.io/api/v1/developer/credits/usage-by-operation?range=month" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns UsageByOperation with operations (list[OperationUsage], each with operation, total_micro_usd / total_usd, and event_count) plus the window totals total_micro_usd and total_events.

iter

Auto-paging iterator over the entire ledger.

for entry in client.credits.iter(page_size=100):
    print(entry.balance_after, entry.operation)  # balance_after in µUSD
# Page manually with limit + offset until fewer than `limit` rows return.
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].

estimate

Pre-flight cost check before invoking a paid operation. Prices are set in USD — for example, training is billed per GPU-minute and image generation/editing per image — and estimate returns the live price for the operation, so you never need to hard-code costs.

ArgTypeDefaultNotes
operationstrrequiredOperation slug (e.g. "training_a10g")
quantityint1Number of units to price
estimate = client.credits.estimate("training_a10g", quantity=30)

print(f"${estimate.per_unit_usd:.4f} per {estimate.unit}")
print(f"Total: ${estimate.total_usd:.2f} for {estimate.quantity} {estimate.unit}(s)")
print("Sufficient:", estimate.sufficient)
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:

FieldMeaning
operationThe operation slug you passed.
unitUnit of measure — "minute", "image", "run", etc.
quantityNumber of units priced.
micro_usd_per_unitPer-unit price in micro-USD (µUSD).
total_micro_usdmicro_usd_per_unit × quantity, in µUSD.
remaining_micro_usdThe org’s spendable compute credit when the estimate ran (µUSD).
sufficientTrue if the org can currently afford total_micro_usd.

total_usd / per_unit_usd / remaining_usd are the float-dollar convenience properties.

Common operation slugs: training_a10g, training_a100, training_h100, sam3_auto_annotation, inference_t4, image_generate_imagen_fast, image_edit_gemini_flash. The full, authoritative price list lives server-side — call estimate for the current per-unit price rather than assuming a fixed cost.

sufficient=True is not a guarantee — another caller may drain the wallet between the estimate and the actual call. The authoritative answer is the operation’s own PaymentRequiredError.

Tier-gated operations. image_generate_*, image_edit_*, 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 org the gated endpoints return 403 tier_restricted before any credit is debited.

Gating in workflows

full_pipeline already gates on wallet balance before kicking off paid phases:

from pictograph.pipelines import full_pipeline

report = full_pipeline(
    client,
    dataset_name="…", folder="…", classes=…, pipeline="yolox",
    min_credits=1,             # skip annotate + train if wallet is short
)
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:
    # e.credit_cost / e.credits_remaining are integer µUSD (e.unit == "micro_usd")
    print(f"Need ${e.credit_cost / 1e6:.2f}, have ${e.credits_remaining / 1e6:.2f}")
    print(f"Top up at: {e.upgrade_url}")

A PaymentRequiredError is raised when an operation’s cost exceeds the org’s spendable compute credit — that is, the included allowance plus any remaining overage budget. Raising the plan or the Budget cap clears it.

Refunds

The training pipeline auto-refunds unused GPU minutes when:

  • A run is cancelled mid-training.
  • A run failed before consuming the full timeout budget.

Refunds appear as positive ledger entries (operation training_refund_<gpu>). No SDK call required.

Common errors

StatusExceptionCause
422ValidationErroroperation slug is not a known credit operation
402PaymentRequiredError(raised by the operation being estimated, not by estimate itself)
Copied to clipboard