API Credits Endpoints

Endpoints Overview

MethodPathAuthDescription
GET/api/payments/packsList available credit packs
POST/api/payments/checkoutCreate a Stripe checkout session
GET/api/payments/session/:sessionIdGet checkout session status
GET/api/payments/historyGet payment history
GET/api/payments/balancesGet current unified balance
GET/api/account/balancesAlternative 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:

FieldDescription
packIdUnique identifier (e.g., micro, basic)
nameDisplay name
creditsNumber of credits included
pricePrice in cents (e.g., 4900 = $49.00)
pricePerCreditEffective 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

FieldTypeRequiredDescription
itemsarrayNo*Array of pack selections with quantity
items[].packIdstringYesPack identifier from the packs endpoint
items[].quantitynumberYesHow many of this pack to purchase
packIdstringNo*Single pack ID (backward-compatible)
orgIdnumberNoOrganization 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

  1. Call this endpoint to create the checkout session
  2. Redirect the user to the url returned
  3. The user completes payment on Stripe’s hosted page
  4. Stripe calls the webhook, credits are added automatically
  5. 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

ParameterLocationDescription
sessionIdURL pathThe 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:

FieldDescription
paymentIdInternal payment identifier
statuscompleted, pending, failed
amountTotal charged (in cents)
itemsArray of packs purchased
createdAtWhen the payment was initiated
completedAtWhen 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:

  1. The webhook fires with the payment details
  2. TimeProof verifies the Stripe signature
  3. Credits are added to the user’s account (or organization)
  4. A notification is sent to the user via WebSocket

You don’t need to call this endpoint directly. It’s listed here for completeness.

Use the live product for timestamping and verification.

The company site owns the technical reference. The app handles runtime workflows.