Notice: Syft Router is in ALPHA. A major update will arrive mid-November — stay connected for updates.

Accounting & Pricing

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.

Overview

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.

📊 Usage Tracking

Monitor requests, tokens, and performance across all your services with real-time analytics and detailed reporting.

💰 Automated Billing

Users are charged based on their usage with automatic payment processing and built-in fraud protection.

📈 Analytics

View usage patterns and revenue through detailed dashboards with real-time updates and trend analysis.

🔒 Access Control

The system enforces rate limits and quotas to maintain service quality and prevent abuse automatically.

Pricing Models

Per-Request Pricing

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"
}
✅ This pricing model works best for:
  • Search services - Each query has similar computational cost
  • Simple chat responses - Fixed interaction patterns
  • Predictable workloads - Consistent resource usage per request
  • Fixed-cost operations - Image processing, data analysis, etc.

Per-Token Pricing

🚧 Coming Soon

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.

Implementing Accounting

The accounting system integrates with your router services through OpenMined's hosted accounting service. Here's how to implement it properly:

Basic Integration

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')
        )

Transaction Handling

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)

Usage Tracking

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
    )

How the Accounting System Works

OpenMined's hosted accounting service handles all the billing complexity with a sophisticated transaction flow:

1

Transaction Creation

When a paid request comes in, a transaction is created but not yet charged. This reserves the user's balance without actually deducting money.

2

Service Execution

Your router processes the request (chat, search, etc.) within the transaction context. This ensures payment is tied to successful service delivery.

3

Conditional Payment

Payment is only confirmed if the service request was successful. Failed requests automatically release the reserved balance.

4

Usage Tracking

All usage data (tokens, cost, response time, metadata) is automatically recorded in the accounting system for analytics.

5

Analytics

Data flows into dashboards for monitoring and optimization, giving you insights into usage patterns and revenue.

Pricing Configuration

Setting Router Pricing

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
  }
}