Settle Sessions
When usage tracking is complete, stop the session and settle it to generate an invoice. Settlement creates a ledger entry and optionally generates an invoice for the final usage amount.
Stop Session
Stop a session and optionally settle it immediately.
Endpoint
/v1/metered-billing/sessions/{session_id}/stopAuthorization: Bearer <ORVION_API_KEY> or X-API-Key: <ORVION_API_KEY>
Content-Type: application/json
Request Body
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| settle | boolean | Optional | Whether to settle the session immediately (default: false) | true |
Example: cURL
# Stop without settlingcurl -X POST "https://api.orvion.sh/v1/metered-billing/sessions/sess_abc123/stop" \-H "Authorization: Bearer $ORVION_API_KEY" \-H "Content-Type: application/json" \-d '{"settle": false}'# Stop and settle immediatelycurl -X POST "https://api.orvion.sh/v1/metered-billing/sessions/sess_abc123/stop" \-H "Authorization: Bearer $ORVION_API_KEY" \-H "Content-Type: application/json" \-d '{"settle": true}'
Example: Python SDK
from orvion import OrvionClient# Initialize clientorvion = OrvionClient(api_key="your_api_key")# Get sessionsession = await orvion.usage.get_session("sess_abc123")# Stop without settlingresult = await session.stop(settle=False)print(f"Session stopped: {result.session.status}")# Or stop and settle immediatelyresult = await session.stop(settle=True)if result.settlement:print(f"Settled: ${result.settlement.settled_amount}")print(f"Invoice ID: {result.settlement.invoice_id}")
Example: Node.js SDK
import { OrvionClient } from '@orvion/sdk';// Initialize clientconst orvion = new OrvionClient({ apiKey: 'your_api_key' });// Get sessionconst session = await orvion.usage.getSession('sess_abc123');// Stop without settlingconst result = await session.stop({ settle: false });console.log(`Session stopped: ${result.session.status}`);// Or stop and settle immediatelyconst result2 = await session.stop({ settle: true });if (result2.settlement) {console.log(`Settled: $${result2.settlement.settledAmount}`);console.log(`Invoice ID: ${result2.settlement.invoiceId}`);}
Response Example
{
"session": {
"id": "sess_abc123",
"status": "stopped",
"customer_ref": "user_123",
"usage": {
"total_seconds": 1000,
"total_amount": "2.50"
},
"stopped_at": "2025-01-15T11:00:00Z"
},
"settlement": {
"settled_amount": "2.50",
"invoice_id": "inv_xyz789",
"already_settled": false
}
}
Settle Session
Settle a stopped session to generate an invoice. Idempotent - safe to retry.
Endpoint
/v1/metered-billing/sessions/{session_id}/settleAuthorization: Bearer <ORVION_API_KEY> or X-API-Key: <ORVION_API_KEY>
Example: cURL
curl -X POST "https://api.orvion.sh/v1/metered-billing/sessions/sess_abc123/settle" \-H "Authorization: Bearer $ORVION_API_KEY"
Example: Python SDK
from orvion import OrvionClient# Initialize clientorvion = OrvionClient(api_key="your_api_key")# Get sessionsession = await orvion.usage.get_session("sess_abc123")# Settle the sessionresult = await session.settle()print(f"Settled amount: ${result.settled_amount}")print(f"Invoice ID: {result.invoice_id}")print(f"Already settled: {result.already_settled}")
Example: Node.js SDK
import { OrvionClient } from '@orvion/sdk';// Initialize clientconst orvion = new OrvionClient({ apiKey: 'your_api_key' });// Get sessionconst session = await orvion.usage.getSession('sess_abc123');// Settle the sessionconst result = await session.settle();console.log(`Settled amount: $${result.settledAmount}`);console.log(`Invoice ID: ${result.invoiceId}`);console.log(`Already settled: ${result.alreadySettled}`);
Response Example
{
"settled_amount": "2.50",
"invoice_id": "inv_xyz789",
"already_settled": false
}
Settlement Flow
1. Session Active 2. Stop Session 3. Settle Session
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ Status: │ │ POST /stop │ │ POST /settle│
│ active │ │ │ │ │
│ │ │ Status: │ │ Status: │
│ Usage: │ ──▶ │ stopped │ ──▶ │ settled │
│ 1000s │ │ │ │ │
│ $2.50 │ │ Usage: │ │ Invoice: │
│ │ │ 1000s │ │ inv_xyz789 │
│ │ │ $2.50 │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
What Happens During Settlement
- Balance Deduction: The final usage amount is deducted from the customer's balance
- Ledger Entry: A debit entry is created in the balance ledger
- Invoice Generation: An invoice is created for the settled amount
- Session Update: Session status changes to
settledandsettled_atis set
Idempotency
Settlement is idempotent. If you call settle() multiple times:
- The first call settles the session and generates an invoice
- Subsequent calls return the same settlement result with
already_settled: true - No duplicate invoices or ledger entries are created
Insufficient Balance
If the customer's balance is insufficient when settling:
Response (402 Payment Required)
{
"detail": "Insufficient balance to settle session"
}
Handling
You can:
- Top up balance and retry settlement
- Allow negative balance by adjusting your balance service logic
- Stop session without settling and handle payment separately
Invoice Details
The generated invoice includes:
- Customer reference: From the session
- Amount: Settled amount from usage
- Currency: From session pricing
- Line items: Usage details (seconds, rate, total)
- Metadata: Session metadata if provided
You can retrieve the invoice via the Invoices API:
invoice = await orvion.invoices.get("inv_xyz789")
print(f"Invoice amount: ${invoice.total_amount}")
print(f"Status: {invoice.status}")
Complete Example
from orvion import OrvionClient
from orvion.usage import UsagePricing, UsageCap
async def complete_metered_billing_flow():
orvion = OrvionClient(api_key="your_api_key")
# 1. Top up balance
balance = await orvion.metered_billing.top_up_balance(
customer_ref="user_123",
currency="USD",
amount="100.00"
)
print(f"Balance: ${balance.available_amount}")
# 2. Create session
session = await orvion.usage.create_session(
customer_id="user_123",
pricing=UsagePricing(
currency="USD",
unit="second",
unit_price="0.0025"
),
cap=UsageCap(amount="50.00")
)
print(f"Session created: {session.id}")
# 3. Report usage (simulated)
for i in range(10):
result = await session.tick(seconds=10)
if result.insufficient_balance or result.cap_reached:
break
print(f"Tick {i+1}: {result.session_status}")
# 4. Stop and settle
result = await session.stop(settle=True)
if result.settlement:
print(f"Settled: ${result.settlement.settled_amount}")
print(f"Invoice: {result.settlement.invoice_id}")
# 5. Check final balance
balance = await orvion.metered_billing.get_balance(balance.id)
print(f"Final balance: ${balance.available_amount}")
Important Notes
Session Status
- active - Session is running, accepting ticks
- stopped - Session stopped, not accepting ticks, not yet settled
- settled - Session settled, invoice generated
Settlement Timing
You can settle:
- Immediately when stopping:
stop(settle=True) - Later after stopping:
stop(settle=False)thensettle()
Invoice Generation
Invoices are automatically created during settlement. The invoice:
- References the session
- Includes usage details
- Can be retrieved via the Invoices API
- Can be sent to customers via the Invoicing API
Error Responses
402 Payment Required
{
"detail": "Insufficient balance to settle session"
}
404 Not Found
{
"detail": "Session not found"
}
409 Conflict
{
"detail": "Session must be stopped before settling"
}
Next Steps
- View Session Details - Check usage statistics
- Manage Balances - View balance history
- Invoice Management - Send and manage invoices