60db Memory is pay-as-you-go, not subscription-based. Every operation deducts a precise amount from your workspace’s wallet, and every charge is logged in a transaction audit trail you can read via GET /memory/usage.
No minimum commitment, no seat pricing, no overage surprises. You pay only for the operations you run, and when you run out of credits the service returns 402 Insufficient Credits until you top up your wallet.
Rates
| Operation | Unit | Rate | Example |
|---|
| Ingest — store a memory | per 1,000 characters | $0.0001 | 5,000-char memory = $0.0005 |
| Document upload — extract fee | per megabyte | $0.003 | 2 MB PDF = $0.006 (plus ingest cost below) |
| Document upload — ingest fee | per 1,000 characters | $0.0001 | 50,000 chars extracted = $0.005 |
| Search — hybrid recall | per query | $0.0003 | 1,000 searches = $0.30 |
| Context assembly — LLM-ready prompt | per query | $0.0005 | 1,000 queries = $0.50 |
What these add up to in practice
| Scenario | Monthly cost |
|---|
| Knowledge base of 100 MB uploaded + 10,000 searches/mo | ~$23/mo |
| Personal assistant — 1,000 user memories stored (~200 chars each) + 500 searches/day | ~$4.70/mo |
| Enterprise support bot — 1 GB docs + 100,000 searches/mo | ~$53/mo |
Compare against proprietary memory services that charge 249–5,000/month flat subscriptions regardless of usage. For most workloads, 60db’s pay-as-you-go model is 5–50x cheaper.
How the wallet works
Your 60db workspace has its own USD wallet. Every billable operation (Memory, TTS, STT, LLM) deducts from the workspace wallet atomically:
- Top up via the Dashboard billing page using Dodo Payments.
- Use the API — every billable request is charged upfront from the workspace wallet.
- Automatic refund on failure — if a request fails after being charged (e.g. the upstream service is unreachable or a document is corrupt), the charge is automatically reversed and logged with a
*_REFUND transaction.
- Monitor spend via
GET /billing/usage-logs for all services, or GET /memory/usage for Memory-specific breakdown.
Every successful memory operation returns three custom headers so you can track spend without polling:
| Header | Meaning |
|---|
x-credit-balance | Your wallet balance after this charge (USD, 6 decimal places) |
x-credit-charged | Amount charged for this specific request (USD, 6 decimal places) |
x-credit-charged-total | Present only on /memory/documents/extract — sum of the extract fee + post-extraction ingest fee |
x-billing-tx | UUID of the transaction_log row (useful for support tickets and manual refunds) |
Example
curl -v -X POST https://api.60db.com/memory/search \
-H "Authorization: Bearer sk_abc123" \
-H "Content-Type: application/json" \
-d '{"query": "user preferences"}' 2>&1 | grep "^< x-"
< x-credit-balance: 9.465200
< x-credit-charged: 0.000300
< x-billing-tx: 84ffd09e-f5a4-42ea-a8fc-f50038392652
Handling 402 Insufficient Credits
When your wallet runs out, all billable memory endpoints return HTTP 402 with a structured error body:
{
"success": false,
"message": "Insufficient credits",
"error_code": "INSUFFICIENT_CREDITS",
"details": {
"required": 0.0003,
"available": 0.00001,
"shortfall": 0.00029
}
}
Your client should catch this and either prompt the user to top up the wallet (via the dashboard) or surface the shortfall in your own UI. Administrative endpoints (GET /memory/collections, GET /memory/:id/status, DELETE /memory/:id, GET /memory/usage) are never billed and never return 402 — they stay available even when the wallet is empty so customers can still inspect, clean up, and check usage.
Automatic refund on failure
60db charges upfront but refunds automatically whenever the downstream work fails. You don’t need to open a ticket — the refund lands in transaction_log as a negative row linked to the original charge via reference_hash_id.
Refunds are triggered on:
| Scenario | Refund behavior |
|---|
| Controller throws an unexpected error (HTTP 5xx) | Full auto-refund via response guard |
| Client validation error (HTTP 4xx) | Full auto-refund (nothing actually ran) |
Memory service unreachable — request queued (202 MEMORY_QUEUED) | Full auto-refund (work won’t happen) |
Document extraction fails (corrupt/unsupported file, 422 EXTRACTION_FAILED) | Full auto-refund of the extract fee |
| Extraction succeeds but wallet can’t cover the post-extract ingest charge | Extract fee refunded, 402 returned with extract_fee_refunded in details |
You can verify a refund by calling GET /memory/usage — the refunds counter increments, and net_spend_usd reflects the reversal.
What is NOT billed
To give you visibility into your data without forcing charges:
- Listing collections (
GET /memory/collections)
- Creating collections (
POST /memory/collections)
- Checking memory status (
GET /memory/:id/status)
- Deleting a memory (
DELETE /memory/:id)
- Service health (
GET /memory/health)
- Reconcile (
POST /memory/reconcile)
- Usage breakdown (
GET /memory/usage)
Setting spend limits
The pay-as-you-go model means you cap spending by capping your wallet balance. Top up only what you want to risk this period. We recommend:
- Small teams: top up 10–50 at a time via the Dashboard billing page and let the wallet drain naturally.
- Production deployments: set a cron that pings
GET /memory/usage daily and alerts your team when net spend crosses a threshold.
- Enterprise: contact sales for committed-use pricing with higher rate limits and dedicated support.