Updated Apr 27, 2026
guides

Billing and usage #

Wallet balance, spendable funds, in-flight holds, and the usage summary endpoint.

DataDistillers bills per-job by actual GPU compute time, not file size or page count. This guide covers how to read your wallet, distinguish spendable funds from in-flight holds, and pull a usage summary.

The billing model

A job's cost = (per-second compute rate) × (actual GPU seconds). No per-page charge, no per-file fee, no minimum.

When you submit a job:

  1. The platform places a hold on your wallet for an estimated cost.
  2. The job runs.
  3. On completion, the hold is settled to the actual cost, usually less than the hold.
  4. The difference is released back to spendable balance.

If a job fails or is cancelled, the entire hold is released. You only pay for compute that produced a result.

Reading the wallet

GET /wallet returns three numbers:

bash
curl -u "$DD_KEY:$DD_SECRET" \
  https://api.datadistillers.com/api/v1/wallet
json
{
  "balance":   125.40,
  "spendable": 119.85,
  "is_frozen": false,
  "frozen_reason": null
}
FieldMeaning
balanceTotal credits deposited and not yet spent.
spendablebalance minus funds held by in-flight jobs. The amount available to start new jobs.
is_frozenIf true, no new jobs can be started. See frozen_reason.
frozen_reasonHuman-readable cause: payment_failed, manual_freeze, compliance_review, etc.

The gap between balance and spendable reflects in-flight holds. After all in-flight jobs complete, spendable rises back to balance (less the actually-spent portion).

Handling a frozen wallet

A frozen wallet rejects new submissions with 402 Payment Required. The freeze persists until cleared by the trigger:

frozen_reasonCleared by
payment_failedAdd funds via the dashboard. Auto-recharge cards retry on next deposit attempt.
manual_freezeLift the freeze in the dashboard.
compliance_reviewResolved by support.

In-flight jobs already accepted before the freeze run to completion and charge normally. The freeze affects only new submissions.

Usage summary

GET /usage?period={7d|30d|90d} returns aggregated spend over a rolling window:

bash
curl -u "$DD_KEY:$DD_SECRET" \
  'https://api.datadistillers.com/api/v1/usage?period=30d'
json
{
  "period":           "30d",
  "period_start":     "2026-04-03T00:00:00Z",
  "period_end":       "2026-05-03T00:00:00Z",
  "total_jobs":       2841,
  "successful_jobs":  2779,
  "failed_jobs":      62,
  "total_spend":      87.42
}

total_spend is the sum of cost across all completed jobs in the window. In-flight holds are excluded; only finalised charges count. So total_spend for a window that ends "now" can be lower than what the wallet shows as the recent spend, because the most recent jobs may still be held.

Building a balance monitor

A simple alerting cron that pages on low balance:

py
import os, requests

THRESHOLD = 50.00              # warn when spendable drops below this
AUTH      = (os.environ['DD_KEY'], os.environ['DD_SECRET'])

w = requests.get('https://api.datadistillers.com/api/v1/wallet', auth=AUTH).json()

if w['is_frozen']:
    page(f"DD wallet frozen: {w['frozen_reason']}")
elif w['spendable'] < THRESHOLD:
    warn(f"DD spendable below threshold: ${w['spendable']:.2f}")

Run it every 5–15 minutes from cron or your scheduler. Pair with the usage endpoint for a weekly spend digest if budgets matter to your org.

Per-job cost visibility

The cost of an individual job appears on the artifact response after completion. Look at processing_duration_seconds and the per-second rate on your account:

bash
curl -u "$DD_KEY:$DD_SECRET" \
  https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1 | \
  jq '{ duration: .processing_duration_seconds, status: .status }'

For finer granularity (e.g. tracking spend per template or per business unit), correlate artifact_id against tags you set at submit and aggregate in your data warehouse; there's no built-in segmentation in the usage endpoint.

Esc
↑↓Navigate↵OpenEscClose