API Credits Endpoints
Endpoints Overview
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/payments/packs | ❌ | List available credit packs |
| POST | /api/payments/checkout | ✅ | Create a Stripe checkout session |
| GET | /api/payments/session/:sessionId | ✅ | Get checkout session status |
| GET | /api/payments/history | ✅ | Get payment history |
| GET | /api/payments/balances | ✅ | Get current unified balance |
| GET | /api/account/balances | ✅ | Alternative unified-balance endpoint |
List Credit Packs
GET /api/payments/packs
This is a public endpoint — no authentication required. Returns the current one-time pack catalog for the unified credit system.
Response
The response includes the current pack catalog. Each pack includes:
| Field | Description |
|---|---|
packId | Unique identifier (e.g., micro, basic) |
name | Display name |
credits | Number of credits included |
price | Price in cents (e.g., 4900 = $49.00) |
pricePerCredit | Effective cost per credit |
Use this endpoint to build a custom purchasing UI or to programmatically select the best pack for a given need.
Check Balances
GET /api/payments/balances
Returns the authenticated user’s current unified credit balance. Alternatively, GET /api/account/balances returns the same data.
Response
{
"balance": 842
}
When to Check Balances
Call this before creating timestamps to ensure sufficient credits. Scheduled timestamps cost 1 credit per file, verified instant timestamps cost 2 credits per file, and Legal-Grade adds a per-batch charge. Checking first provides a better user experience than discovering the shortfall after submission.
Create Checkout Session
POST /api/payments/checkout
Content-Type: application/json
Creates a Stripe checkout session for purchasing credits. Returns a URL to redirect the user to Stripe’s hosted payment page.
Request Body (Multiple Items)
{
"items": [
{ "packId": "micro", "quantity": 1 },
{ "packId": "basic", "quantity": 1 }
],
"orgId": null
}
Request Body (Single Item)
{
"packId": "basic",
"orgId": null
}
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
items | array | No* | Array of pack selections with quantity |
items[].packId | string | Yes | Pack identifier from the packs endpoint |
items[].quantity | number | Yes | How many of this pack to purchase |
packId | string | No* | Single pack ID (backward-compatible) |
orgId | number | No | Organization to receive credits (null = personal) |
*Provide either items array or packId — not both.
Response
{
"sessionId": "cs_test_...",
"paymentId": 1,
"url": "https://checkout.stripe.com/...",
"itemCount": 3
}
Workflow
- Call this endpoint to create the checkout session
- Redirect the user to the
urlreturned - The user completes payment on Stripe’s hosted page
- Stripe calls the webhook, credits are added automatically
- The user is redirected back to your application
Check Checkout Status
GET /api/payments/session/:sessionId
Check the status of a specific checkout session. Useful for confirming payment completion after the user returns from Stripe.
Parameters
| Parameter | Location | Description |
|---|---|---|
sessionId | URL path | The Stripe session ID from the checkout response |
Payment History
GET /api/payments/history
Returns the authenticated user’s payment history, ordered by most recent first.
Response
Each payment record includes:
| Field | Description |
|---|---|
paymentId | Internal payment identifier |
status | completed, pending, failed |
amount | Total charged (in cents) |
items | Array of packs purchased |
createdAt | When the payment was initiated |
completedAt | When payment was confirmed |
Integration Example
Complete Purchase Flow (JavaScript)
// 1. Check current balance
const balances = await fetch('/api/payments/balances', {
credentials: 'include'
}).then(r => r.json());
console.log(`Unified balance: ${balances.balance} credits`);
// 2. If balance is too low for the next job, create checkout
if (balances.balance < 100) {
const checkout = await fetch('/api/payments/checkout', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
items: [{ packId: 'micro', quantity: 1 }]
})
}).then(r => r.json());
// 3. Redirect to Stripe
window.location.href = checkout.url;
}
Python — Check Balance Before Timestamping
import requests
session = requests.Session()
# ... authenticate first (see API Authentication) ...
# Check balance
balances = session.get(
"http://localhost:5050/api/payments/balances"
).json()
if balances["balance"] >= files_to_timestamp:
# Proceed with timestamp creation
pass
else:
# Need to purchase more credits
checkout = session.post(
"http://localhost:5050/api/payments/checkout",
json={"packId": "micro"}
).json()
print(f"Purchase credits at: {checkout['url']}")
Webhook Processing
The webhook endpoint (POST /api/payments/webhook) is called by Stripe, not by your application. It uses Stripe’s signature verification — not session cookies — to authenticate the request.
When Stripe confirms a payment:
- The webhook fires with the payment details
- TimeProof verifies the Stripe signature
- Credits are added to the user’s account (or organization)
- A notification is sent to the user via WebSocket
You don’t need to call this endpoint directly. It’s listed here for completeness.
Related Guides
- Credit System Explained — how unified credits, verification, and LG upgrades work
- Buying Credits — purchasing through the web interface
- Getting Started — choose between packs and verified plans
- API Timestamp Endpoints — spending credits
Use the live product for timestamping and verification.
The company site owns the technical reference. The app handles runtime workflows.