This guide explains how usage tracking, billing, and pricing work for your router services. Learn about OpenMined's hosted accounting service and how to implement monetization.
Syft Router accounting uses OpenMined's hosted accounting service to handle billing and usage tracking for your router. The system provides comprehensive functionality for monetizing your AI services.
Monitor requests, tokens, and performance across all your services with real-time analytics and detailed reporting.
Users are charged based on their usage with automatic payment processing and built-in fraud protection.
View usage patterns and revenue through detailed dashboards with real-time updates and trend analysis.
The system enforces rate limits and quotas to maintain service quality and prevent abuse automatically.
This model charges users a fixed amount for each API call, making costs predictable for both you and your users:
{
"pricing_type": "per_request",
"amount": 0.01,
"currency": "USD",
"description": "$0.01 per search query"
}
Per-token pricing is not currently supported. We will add this feature in a future beta version to enable more granular billing for language model usage.
The accounting system integrates with your router services through OpenMined's hosted accounting service. Here's how to implement it properly:
Here's a real example from a CustomChatService showing proper accounting integration:
# Real example from CustomChatService showing proper accounting integration
class CustomChatService(ChatService):
def __init__(self, config: RouterConfig):
super().__init__(config)
# This connects to OpenMined's hosted accounting service
self.accounting_client: UserClient = self.config.accounting_client()
logger.info(f"Initialized accounting client: {self.accounting_client}")
self.app_name = self.config.project.name
# Initialize your language model client
self.client = OpenAI(
api_key=config.get('openai_api_key'),
base_url=config.get('base_url', 'https://api.openai.com/v1')
)
The core of the accounting system is the transaction pattern. Here's how it works:
def generate_chat(
self,
model: str,
messages: List[Message],
user_email: EmailStr,
transaction_token: Optional[str] = None,
options: Optional[GenerationOptions] = None,
) -> ChatResponse:
# Prepare request payload for your language model
payload = {
"model": model or self.default_model,
"messages": [{"role": msg.role, "content": msg.content} for msg in messages],
"stream": False,
}
# Handle payment transaction - this is where the accounting magic happens!
# The transaction is created first, then confirmed only if the AI request succeeds.
query_cost = 0.0
if self.pricing > 0 and transaction_token:
with self.accounting_client.delegated_transfer(
user_email, # Who is being charged
amount=self.pricing, # How much to charge
token=transaction_token, # Payment authorization from user
app_name=self.app_name, # Your router name for billing
app_ep_path="/chat", # Which endpoint was used
) as payment_txn:
# Only make the expensive API call inside the transaction context
response = self.client.chat.completions.create(**payload)
# Only confirm payment if we got a valid response
# This ensures users are only charged for successful requests!
if response.choices:
payment_txn.confirm() # This actually charges the user
query_cost = self.pricing
elif self.pricing > 0 and not transaction_token:
raise ValueError(
"Transaction token is required for paid services. Please provide a transaction token."
)
else:
# Free service - no payment needed
response = self.client.chat.completions.create(**payload)
Always return detailed usage information for analytics and billing transparency:
# Convert response to SyftBox format with usage tracking
choice = response.choices[0]
usage = ChatUsage(
prompt_tokens=response.usage.prompt_tokens,
completion_tokens=response.usage.completion_tokens,
total_tokens=response.usage.total_tokens,
)
return ChatResponse(
id=UUID(response.id),
model=response.model,
message=Message(role="assistant", content=choice.message.content),
usage=usage,
provider_info={"provider": "openai", "finish_reason": choice.finish_reason},
cost=query_cost, # This gets tracked for analytics
)
OpenMined's hosted accounting service handles all the billing complexity with a sophisticated transaction flow:
When a paid request comes in, a transaction is created but not yet charged. This reserves the user's balance without actually deducting money.
Your router processes the request (chat, search, etc.) within the transaction context. This ensures payment is tied to successful service delivery.
Payment is only confirmed if the service request was successful. Failed requests automatically release the reserved balance.
All usage data (tokens, cost, response time, metadata) is automatically recorded in the accounting system for analytics.
Data flows into dashboards for monitoring and optimization, giving you insights into usage patterns and revenue.
Configure pricing through the dashboard when publishing your router:
# Example pricing configuration
{
"router_name": "my-ai-router",
"services": {
"chat": {
"pricing_type": "per_request",
"amount": 0.02,
"currency": "USD",
"description": "Premium AI chat with GPT-4"
},
"search": {
"pricing_type": "per_request",
"amount": 0.01,
"currency": "USD",
"description": "Vector search in document collection"
}
},
"free_tier": {
"chat": 10, # 10 free requests per day
"search": 20 # 20 free requests per day
}
}