Skip to main content
The Facilitator is the centralized settlement service for the ATP Protocol. It handles usage token parsing, payment calculation, and Solana payment execution for all ATP-protected services.

What is the Facilitator?

The Facilitator is a service that:
  • Parses usage tokens from various API formats (OpenAI, Anthropic, Google, etc.)
  • Calculates payment amounts based on token usage and pricing
  • Executes Solana blockchain transactions for payments
  • Automatically splits payments between treasury and recipients

Base URLs

  • Production: https://facilitator.swarms.world

Endpoints

Health Check

Check if the Facilitator service is available and healthy.

GET /health

Request No parameters required. Response
FieldTypeDescription
statusstringService status (e.g., “healthy”)
servicestringService name
versionstringAPI version
Example Response
{
  "status": "healthy",
  "service": "ATP Settlement Service",
  "version": "1.0.0"
}
Code Example
import httpx

# Check service health
response = httpx.get("https://facilitator.swarms.world/health")
health = response.json()

if health["status"] == "healthy":
    print(f"Service is operational (version {health['version']})")
else:
    print("Service may be experiencing issues")

Parse Usage Tokens

Convert usage data from any API format into a standardized format.

POST /v1/settlement/parse-usage

Automatically detects and parses usage data from multiple formats, including nested structures. Supported Formats
FormatToken Fields
OpenAIprompt_tokens, completion_tokens, total_tokens
Anthropicinput_tokens, output_tokens, total_tokens
Google/GeminipromptTokenCount, candidatesTokenCount, totalTokenCount
Coheretokens, input_tokens, output_tokens
Nestedusage.usage, meta.usage, statistics
Request Parameters
ParameterTypeRequiredDescription
usage_dataobjectYesUsage data in any supported format. Can be the entire response body or just the usage portion.
Response Fields
FieldTypeDescription
input_tokensinteger | nullNumber of input/prompt tokens
output_tokensinteger | nullNumber of output/completion tokens
total_tokensinteger | nullTotal number of tokens
Example: OpenAI Format
import httpx

# Parse OpenAI format usage data
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/parse-usage",
    json={
        "usage_data": {
            "prompt_tokens": 100,
            "completion_tokens": 50,
            "total_tokens": 150
        }
    }
)

parsed = response.json()
print(f"Input: {parsed['input_tokens']}, Output: {parsed['output_tokens']}")
# Output: Input: 100, Output: 50
Example: Anthropic Format
# Parse Anthropic format usage data
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/parse-usage",
    json={
        "usage_data": {
            "input_tokens": 100,
            "output_tokens": 50
        }
    }
)

parsed = response.json()
print(f"Total tokens: {parsed['total_tokens']}")
# Output: Total tokens: 150
Example: Nested Format
# Parse nested usage data
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/parse-usage",
    json={
        "usage_data": {
            "response": "Agent output here",
            "meta": {
                "usage": {
                    "input_tokens": 100,
                    "output_tokens": 50
                }
            }
        }
    }
)

parsed = response.json()
print(parsed)
# Output: {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150}
Example: Using with ATP Client
from atp.client import ATPClient

client = ATPClient()

# Parse usage from any format
usage = await client.parse_usage({
    "prompt_tokens": 100,
    "completion_tokens": 50
})

print(f"Parsed usage: {usage}")

Calculate Payment

Calculate payment amounts without executing any transaction. Useful for previewing costs before payment.

POST /v1/settlement/calculate-payment

Request Parameters
ParameterTypeRequiredDescription
usageobjectYesUsage data containing token counts. Supports same formats as parse-usage endpoint.
input_cost_per_million_usdnumberYesCost per million input tokens in USD
output_cost_per_million_usdnumberYesCost per million output tokens in USD
payment_tokenstringNoToken to use for payment. Must be "SOL" or "USDC". Default: "SOL"
Response Fields
FieldTypeDescription
statusstringStatus: "calculated" or "skipped" (if zero cost)
pricingobjectPricing breakdown (see Pricing Object below)
payment_amountsobject | nullPayment amounts in token units (null if zero cost)
token_price_usdnumber | nullCurrent token price in USD
reasonstring | nullReason if calculation was skipped
Pricing Object
FieldTypeDescription
usd_costnumberTotal USD cost
sourcestringSource of pricing rates
input_cost_per_million_usdnumberInput cost rate
output_cost_per_million_usdnumberOutput cost rate
input_cost_usdnumberCalculated input cost in USD
output_cost_usdnumberCalculated output cost in USD
input_tokensinteger | nullNumber of input tokens
output_tokensinteger | nullNumber of output tokens
total_tokensinteger | nullTotal tokens
Payment Amounts Object
FieldTypeDescription
total_amount_unitsintegerTotal payment in smallest token units (lamports for SOL)
total_amount_tokennumberTotal payment in token units (SOL)
fee_amount_unitsintegerTreasury fee in smallest token units
fee_amount_tokennumberTreasury fee in token units
agent_amount_unitsintegerAgent payment in smallest token units
agent_amount_tokennumberAgent payment in token units
Example: Calculate Payment
import httpx

# Calculate payment for 1000 input tokens and 500 output tokens
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/calculate-payment",
    json={
        "usage": {
            "input_tokens": 1000,
            "output_tokens": 500,
            "total_tokens": 1500
        },
        "input_cost_per_million_usd": 2.5,
        "output_cost_per_million_usd": 10.0,
        "payment_token": "SOL"
    }
)

result = response.json()

print(f"USD Cost: ${result['pricing']['usd_cost']:.4f}")
print(f"SOL Amount: {result['payment_amounts']['total_amount_token']:.6f} SOL")
print(f"Treasury Fee: {result['payment_amounts']['fee_amount_token']:.6f} SOL")
print(f"Agent Payment: {result['payment_amounts']['agent_amount_token']:.6f} SOL")
print(f"Token Price: ${result['token_price_usd']:.2f}")

# Output:
# USD Cost: $0.0075
# SOL Amount: 0.001250 SOL
# Treasury Fee: 0.000063 SOL
# Agent Payment: 0.001188 SOL
# Token Price: $20.00
Example: Using with ATP Client
from atp.client import ATPClient
from atp.schemas import PaymentToken

client = ATPClient()

# Calculate payment
payment = await client.calculate_payment(
    usage={"input_tokens": 1000, "output_tokens": 500},
    input_cost_per_million_usd=2.5,
    output_cost_per_million_usd=10.0,
    payment_token=PaymentToken.SOL
)

print(f"Total cost: ${payment['pricing']['usd_cost']:.4f}")
Example: Check if Payment is Zero
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/calculate-payment",
    json={
        "usage": {"input_tokens": 0, "output_tokens": 0},
        "input_cost_per_million_usd": 2.5,
        "output_cost_per_million_usd": 10.0
    }
)

result = response.json()

if result["status"] == "skipped":
    print(f"Payment skipped: {result.get('reason', 'Zero cost')}")
else:
    print(f"Payment required: {result['payment_amounts']['total_amount_token']} SOL")

Execute Settlement

Execute a payment transaction on the Solana blockchain. This endpoint calculates the payment and sends it to both the treasury (fee) and recipient (agent payment).

POST /v1/settlement/settle

WARNING: This endpoint requires your wallet private key. The private key is used in-memory only and never stored or logged. Request Parameters
ParameterTypeRequiredDescription
private_keystringYesSolana wallet private key. JSON array format (e.g., "[1,2,3,...]") or base58 string
usageobjectYesUsage data containing token counts. Supports same formats as parse-usage endpoint
input_cost_per_million_usdnumberYesCost per million input tokens in USD
output_cost_per_million_usdnumberYesCost per million output tokens in USD
recipient_pubkeystringYesSolana public key of the recipient wallet (base58). Receives net payment after fees
payment_tokenstringNoToken to use. Must be "SOL" or "USDC". Default: "SOL"
skip_preflightbooleanNoSkip preflight simulation. Faster but may fail. Default: false
commitmentstringNoSolana commitment level. Options: "processed", "confirmed", "finalized". Default: "confirmed"
Commitment Levels
LevelSpeedSecurityDescription
processedFastest (~1-2s)LowMay be rolled back
confirmedMedium (~30-60s)MediumConfirmed by cluster (recommended)
finalizedSlowest (~1-2min)HighCannot be rolled back
Response Fields
FieldTypeDescription
statusstringStatus: "paid" if successful, "skipped" if zero cost
transaction_signaturestring | nullSolana transaction signature if payment executed
pricingobjectComplete cost breakdown (same as calculate-payment)
paymentobject | nullPayment details with splits (null if skipped)
Payment Object
FieldTypeDescription
total_amount_lamportsintegerTotal payment in lamports
total_amount_solnumberTotal payment in SOL
total_amount_usdnumberTotal payment in USD
treasuryobjectTreasury payment details
recipientobjectRecipient payment details
Treasury/Recipient Objects
FieldTypeDescription
pubkeystringWallet public key
amount_lamportsintegerPayment in lamports
amount_solnumberPayment in SOL
amount_usdnumberPayment in USD
Example: Execute Settlement
import httpx

# Execute payment settlement
response = httpx.post(
    "https://facilitator.swarms.world/v1/settlement/settle",
    json={
        "private_key": "[1,2,3,...64 bytes...]",  # Your wallet private key
        "usage": {
            "input_tokens": 1000,
            "output_tokens": 500,
            "total_tokens": 1500
        },
        "input_cost_per_million_usd": 2.5,
        "output_cost_per_million_usd": 10.0,
        "recipient_pubkey": "RecipientWalletAddressHere",
        "payment_token": "SOL",
        "commitment": "confirmed"
    },
    timeout=300.0  # 5 minutes for blockchain confirmation
)

result = response.json()

if result["status"] == "paid":
    print(f"Payment successful!")
    print(f"Transaction: {result['transaction_signature']}")
    print(f"Total: {result['payment']['total_amount_sol']:.6f} SOL")
    print(f"Treasury: {result['payment']['treasury']['amount_sol']:.6f} SOL")
    print(f"Recipient: {result['payment']['recipient']['amount_sol']:.6f} SOL")
    
    # Verify transaction on Solana explorer
    print(f"View on explorer: https://solscan.io/tx/{result['transaction_signature']}")
else:
    print(f"Payment skipped: {result.get('reason', 'Zero cost')}")
Example: Using with ATP Client
from atp.client import ATPClient
from atp.schemas import PaymentToken

client = ATPClient(
    wallet_private_key="[1,2,3,...]",
    settlement_service_url="https://facilitator.swarms.world"
)

# Execute settlement
result = await client.settle(
    usage={"input_tokens": 1000, "output_tokens": 500},
    input_cost_per_million_usd=2.5,
    output_cost_per_million_usd=10.0,
    recipient_pubkey="RecipientPublicKeyHere",
    payment_token=PaymentToken.SOL,
    commitment="confirmed"
)

if result["status"] == "paid":
    print(f"Payment successful! TX: {result['transaction_signature']}")
Example: Complete Flow
import httpx
from atp.client import ATPClient

# Initialize client
client = ATPClient(
    wallet_private_key="[1,2,3,...]",
    settlement_service_url="https://facilitator.swarms.world"
)

# Step 1: Parse usage from OpenAI response
openai_response = {
    "choices": [{"message": {"content": "Hello!"}}],
    "usage": {
        "prompt_tokens": 100,
        "completion_tokens": 50,
        "total_tokens": 150
    }
}

usage = await client.parse_usage(openai_response["usage"])
print(f"Parsed usage: {usage}")

# Step 2: Calculate payment (optional - preview cost)
payment_calc = await client.calculate_payment(
    usage=usage,
    input_cost_per_million_usd=2.5,
    output_cost_per_million_usd=10.0,
    payment_token=PaymentToken.SOL
)

print(f"Estimated cost: ${payment_calc['pricing']['usd_cost']:.4f}")
print(f"SOL amount: {payment_calc['payment_amounts']['total_amount_token']:.6f}")

# Step 3: Execute settlement
result = await client.settle(
    usage=usage,
    input_cost_per_million_usd=2.5,
    output_cost_per_million_usd=10.0,
    recipient_pubkey="RecipientPublicKeyHere",
    payment_token=PaymentToken.SOL
)

if result["status"] == "paid":
    print(f"Payment completed! Transaction: {result['transaction_signature']}")

Payment Splitting

Payments are automatically split between:
  • Treasury: Receives processing fee (default 5%)
  • Recipient: Receives net payment (default 95%)
The treasury public key is configured on the service and cannot be changed by clients. Example Payment Split For a payment of 0.00125 SOL:
  • Treasury fee: 0.0000625 SOL (5%)
  • Recipient payment: 0.0011875 SOL (95%)

Error Handling

Error Response Format

All errors return a consistent format:
{
  "detail": "Error message describing what went wrong"
}

Common Error Codes

CodeDescriptionCommon Causes
400Bad RequestInvalid private key format, invalid pubkey, missing required fields
402Payment RequiredInsufficient wallet balance
500Internal Server ErrorNetwork errors, RPC issues, service errors

Error Handling Example

import httpx

try:
    response = httpx.post(
        "https://facilitator.swarms.world/v1/settlement/settle",
        json={
            "private_key": "[1,2,3,...]",
            "usage": {"input_tokens": 1000, "output_tokens": 500},
            "input_cost_per_million_usd": 2.5,
            "output_cost_per_million_usd": 10.0,
            "recipient_pubkey": "RecipientPublicKeyHere"
        },
        timeout=300.0
    )
    response.raise_for_status()
    result = response.json()
    
except httpx.HTTPStatusError as e:
    if e.response.status_code == 400:
        error_detail = e.response.json().get("detail", "Invalid request")
        print(f"Bad request: {error_detail}")
    elif e.response.status_code == 402:
        print("Insufficient wallet balance. Please add funds.")
    elif e.response.status_code == 500:
        print("Service error. Please try again later.")
    else:
        print(f"HTTP error {e.response.status_code}: {e.response.text}")
        
except httpx.TimeoutException:
    print("Request timed out. Payment may have succeeded - check blockchain.")
    
except Exception as e:
    print(f"Unexpected error: {e}")

Security Best Practices

  1. Use Dedicated Wallets: Use separate wallets for ATP payments, not your main wallet
  2. Monitor Balances: Keep sufficient balance for payments and transaction fees
  3. Verify Transactions: Always verify transaction signatures on Solana Explorer
  4. Test First: Use testnet or small amounts for testing
  5. Never Log Keys: Never log or store private keys in your code

Timeout Recommendations

Settlement operations involve blockchain transactions which take time to confirm:
CommitmentTypical TimeRecommendation
processed1-2 secondsFast but may be rolled back
confirmed30-60 secondsRecommended for most use cases
finalized1-2 minutesMost secure, cannot be rolled back
Recommendation: Use a timeout of at least 300 seconds (5 minutes) for settlement operations.

Common Use Cases

Use Case 1: Preview Payment Before Execution

from atp.client import ATPClient

client = ATPClient()

# First, calculate payment to show user
usage = {"input_tokens": 1000, "output_tokens": 500}
payment_calc = await client.calculate_payment(
    usage=usage,
    input_cost_per_million_usd=2.5,
    output_cost_per_million_usd=10.0
)

print(f"This will cost ${payment_calc['pricing']['usd_cost']:.4f}")
print(f"SOL amount: {payment_calc['payment_amounts']['total_amount_token']:.6f}")

# User confirms, then execute
user_confirmed = True  # In real app, get from user
if user_confirmed:
    result = await client.settle(
        usage=usage,
        input_cost_per_million_usd=2.5,
        output_cost_per_million_usd=10.0,
        recipient_pubkey="RecipientPublicKeyHere",
        wallet_private_key="[1,2,3,...]"
    )

Use Case 2: Handle Different Usage Formats

from atp.client import ATPClient

client = ATPClient()

# Handle OpenAI format
openai_usage = await client.parse_usage({
    "prompt_tokens": 100,
    "completion_tokens": 50
})

# Handle Anthropic format
anthropic_usage = await client.parse_usage({
    "input_tokens": 100,
    "output_tokens": 50
})

# Both return the same normalized format
print(openai_usage)  # {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150}
print(anthropic_usage)  # {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150}

Use Case 3: Monitor Service Health

import httpx
import time

def check_facilitator_health():
    """Check if Facilitator is healthy"""
    try:
        response = httpx.get(
            "https://facilitator.swarms.world/health",
            timeout=5.0
        )
        if response.status_code == 200:
            health = response.json()
            return health["status"] == "healthy"
        return False
    except Exception:
        return False

# Monitor health every 60 seconds
while True:
    if check_facilitator_health():
        print("Facilitator is healthy")
    else:
        print("WARNING: Facilitator may be down")
    time.sleep(60)

Troubleshooting

Problem: Cannot Connect to Facilitator

Solutions:
  • Verify the base URL is correct: https://facilitator.swarms.world
  • Check your network connectivity
  • Verify SSL certificates are valid
  • Check if service is experiencing downtime

Problem: Transaction Failures

Solutions:
  • Verify wallet has sufficient balance (including transaction fees)
  • Check recipient pubkey is valid Solana address
  • Verify private key format is correct (JSON array or base58)
  • Check Solana network status
  • Try increasing timeout or using commitment="processed" for faster confirmation

Problem: Parsing Failures

Solutions:
  • Verify usage data format matches supported formats
  • Check for nested structures (service handles these automatically)
  • Ensure token count fields are present
  • Review error message for specific format issues

Problem: Timeout Errors

Solutions:
  • Increase request timeout (recommended: 300+ seconds)
  • Use commitment="processed" for faster confirmation (less secure)
  • Check blockchain network congestion
  • Verify transaction on Solana explorer after timeout - payment may have succeeded

API Reference Summary

EndpointMethodDescription
/healthGETCheck service health
/v1/settlement/parse-usagePOSTParse usage tokens from various formats
/v1/settlement/calculate-paymentPOSTCalculate payment amounts without executing
/v1/settlement/settlePOSTExecute settlement payment on Solana

Additional Resources