AiMo Network

For Provider

get started with AiMo Network as service provider

Connect your AI model service to AiMo Network and start earning from your AI model usage.

What You'll Achieve

By the end of this guide, you'll have:

  • Generated your provider API key
  • Configured and deployed the AiMo proxy
  • Connected your OpenAI-compatible AI model service
  • Started earning from your AI model usage

Prerequisites

  • Solana wallet with some SOL for transaction fees
  • OpenAI-compatible AI model API endpoint
  • 5-10 minutes to complete setup

Step 1: Generate Provider API Key

Choose your preferred method:

  1. Visit AiMo Network Dashboard
  2. Connect your Solana wallet
  3. Click "Generate Provider Key"
  4. Copy and securely store your key

Your API key format: aimo-sk-v2-[base58-encoded-key]

Option B: CLI

# Install CLI
cargo install aimo-cli

# Generate key (requires wallet signature)
aimo keygen --tag production --valid-for 90 --scopes completion_model

Store your API key securely. It cannot be retrieved after generation.


Step 2: Ensure API Compatibility

Your service must be compatible with OpenAI's chat completion API format.

Required: OpenAI-Compatible Endpoint

Your API must:

  • Accept POST requests to /v1/chat/completions
  • Support OpenAI-formatted JSON requests
  • Return responses matching OpenAI's structure
  • Include usage data in every response for payment calculation

Request Format

POST /v1/chat/completions
Content-Type: application/json

{
  "model": "your-model-name",
  "messages": [
    {"role": "user", "content": "Hello, AI!"}
  ],
  "stream": false,
  "max_tokens": 150,
  "temperature": 0.7
}

Response Format (Non-Streaming)

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help you today?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 15,
    "completion_tokens": 8,
    "total_tokens": 23
  }
}

Response Format (Streaming)

Content-Type: text/event-stream

data: {"choices":[{"delta":{"content":"Hello"}}]}

data: {"choices":[{"delta":{"content":" there!"}}]}

data: {"choices":[{"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":15,"completion_tokens":8,"total_tokens":23}}

data: [DONE]

Critical: Usage Data Required

You must include a usage object in every response to receive payment. Without usage data:

  • Your earnings will be zero for that request
  • Users may experience billing errors
  • Your service may be flagged as non-compliant

Non-streaming: Include usage in the final response object Streaming: Include usage in the last chunk before [DONE]

Adapting Non-OpenAI APIs

If your API uses a different format, create a lightweight adapter:

Python Example:

from flask import Flask, request, jsonify

@app.route('/v1/chat/completions', methods=['POST'])
def openai_compatible():
    data = request.json
    messages = data['messages']

    # Call your native API
    response = your_model.generate(messages)

    # Convert to OpenAI format
    return jsonify({
        'choices': [{
            'message': {
                'role': 'assistant',
                'content': response.text
            },
            'finish_reason': 'stop'
        }],
        'usage': {
            'prompt_tokens': response.prompt_tokens,
            'completion_tokens': response.completion_tokens,
            'total_tokens': response.total_tokens
        }
    })

Popular API Gateways:

  • LiteLLM - Proxy for 100+ LLM APIs
  • Custom middleware in your preferred language

Step 3: Create Configuration File

Create a config.toml file to define your service settings and models.

Configuration Structure

The config file has two main sections:

  1. Router: Connection to AiMo Network
  2. Models: Your AI model endpoints (one or multiple)

Example Configuration

You can configure one or multiple models in a single file. Each model is defined using the [[models]] block, which can be repeated as many times as needed.

[router]
url = "https://devnet.aimo.network"
api_key = "std::env::AIMO_PROVIDER_KEY"

# Configure one or multiple models by adding [[models]] blocks
# Each block defines a separate model with its own settings

# Model 1: OpenAI GPT-4o
[[models]]
name = "gpt-4o"
display_name = "OpenAI: GPT-4o"
provider_name = "openai"
context_length = 128000
input_modalities = ["text"]
output_modalities = ["text"]

[models.pricing]
# USDC per million tokens
prompt = 2.5
completion = 10.0

[models.params]
model = "gpt-4o"
api_base = "https://api.openai.com/v1"
api_key = "std::env::OPENAI_API_KEY"

# Model 2: DeepSeek (optional - add more models as needed)
[[models]]
name = "deepseek-chat-v3"
display_name = "DeepSeek: DeepSeek V3"
provider_name = "deepseek"
context_length = 64000

[models.pricing]
prompt = 0.5
completion = 1.0

[models.params]
model = "deepseek-chat"
api_base = "https://api.deepseek.com/v1"
api_key = "std::env::DEEPSEEK_API_KEY"

# Model 3: Google Gemini (optional - add more models as needed)
[[models]]
name = "gemini-2.5-flash"
display_name = "Google: Gemini 2.5 Flash Preview"
provider_name = "google"
context_length = 1000000

[models.pricing]
prompt = 0.3
completion = 0.85

[models.params]
model = "gemini-2.5-flash"
api_base = "https://generativelanguage.googleapis.com/v1"
api_key = "std::env::GOOGLE_API_KEY"

Single vs Multiple Models: If you only want to offer one model, simply include one [[models]] block. To add more models, repeat the entire [[models]] block with its nested [models.pricing] and [models.params] sections.

Configuration Fields Reference

Router Settings

FieldDescriptionRequired
urlAiMo router endpointYes
api_keyYour provider API keyYes

Model Metadata

FieldDescriptionRequiredExample
nameUnique model identifierYesgpt-4o
display_nameUser-facing nameYesOpenAI: GPT-4o
provider_nameYour provider identifierYesopenai
context_lengthMaximum context windowNo128000
input_modalitiesSupported input typesNo["text", "image"]
output_modalitiesSupported output typesNo["text"]

Pricing

FieldDescriptionUnitRequired
promptInput token costUSDC per 1M tokensYes
completionOutput token costUSDC per 1M tokensYes
imageImage input costUSDC per imageNo

Model Parameters

FieldDescriptionRequired
modelModel identifier for APIYes
api_baseBase URL for API endpointYes
api_keyAuthentication keyYes

Multimodal Model Configuration

For models supporting image inputs:

[[models]]
name = "gpt-4-vision"
display_name = "OpenAI: GPT-4 Vision"
provider_name = "openai"
input_modalities = ["text", "image"]
output_modalities = ["text"]

[models.pricing]
prompt = 10.0
completion = 30.0
image = 1.0  # Per image cost

[models.params]
model = "gpt-4-vision-preview"
api_base = "https://api.openai.com/v1"
api_key = "std::env::OPENAI_API_KEY"

Environment Variables

Set your API keys as environment variables for security:

Linux/macOS:

export AIMO_PROVIDER_KEY="aimo-sk-v2-your-key-here"
export OPENAI_API_KEY="sk-your-openai-key"
export DEEPSEEK_API_KEY="sk-your-deepseek-key"
export GOOGLE_API_KEY="your-google-api-key"

Windows (PowerShell):

$env:AIMO_PROVIDER_KEY="aimo-sk-v2-your-key"
$env:OPENAI_API_KEY="sk-your-openai-key"

In config.toml, reference them with std::env:: prefix:

api_key = "std::env::AIMO_PROVIDER_KEY"

Configuration Best Practices

Security:

  • Always use environment variables for API keys
  • Never commit API keys to version control
  • Use .env files locally (add to .gitignore)

Pricing Strategy:

  • Research competitor pricing
  • Consider your infrastructure costs
  • Account for API provider costs
  • Leave margin for network fees

Model Naming:

  • Use clear, descriptive names
  • Include provider name in display_name
  • Use consistent naming conventions
  • Avoid special characters in name field

Step 4: Deploy the Proxy

Why Docker?

  • No Rust toolchain required
  • Easy updates and scaling
  • Consistent environment across deployments

Create Docker Compose File

Create compose.yml:

services:
  proxy:
    image: ghcr.io/aimoverse/aimo-proxy:main
    container_name: aimo-proxy
    network_mode: host
    volumes:
      - ./config.toml:/etc/proxy/config.toml
    environment:
      CONFIG_FILE_PATH: /etc/proxy/config.toml
      AIMO_PROVIDER_KEY: ${AIMO_PROVIDER_KEY}
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
      GOOGLE_API_KEY: ${GOOGLE_API_KEY}

Run with Docker Compose

# Start proxy in background
docker compose up -d

# View logs
docker compose logs -f

# Stop proxy
docker compose down

Option B: Direct Installation

# Install proxy via Cargo
cargo install aimo-proxy

# Run proxy with your config
aimo-proxy --config config.toml

# Or with verbose logging
aimo-proxy --config config.toml --log-level debug

Verify Connection

Your proxy is running successfully when you see:

[INFO] Connected to router: https://devnet.aimo.network
[INFO] Model registered: gpt-4o
[INFO] Model registered: deepseek-chat-v3
[INFO] Ready to serve requests

The proxy automatically reconnects if the router restarts. This is normal during active development.

Configuration Validation

Test your configuration before deployment:

# Dry-run to validate config
aimo-proxy --config config.toml --validate

# Run with verbose logging
aimo-proxy --config config.toml --log-level debug

Step 5: Start Earning

How Payments Work

  1. User Request: User sends request, estimated cost is locked from their escrow
  2. Proxy Routes: Request forwarded to your model endpoint
  3. Service Responds: Your API returns response with usage data
  4. Usage Tracking: Actual token usage is reported
  5. Auto-Settlement: Payment transfers to your provider account based on actual usage
  6. Withdrawal: Accumulated earnings can be withdrawn to your wallet

Payment Flow Details

User Escrow → Lock Funds → Process Request → Report Usage → Settle Payment → Provider Account
  • Lock Amount: Estimated based on max_tokens and your pricing
  • Actual Settlement: Based on actual usage data from your response
  • Provider Earnings: Accumulate in your managed provider account

Withdraw Earnings

Visit the dashboard to:

  • View accumulated earnings in real-time
  • Withdraw USDC to your Solana wallet
  • Track usage statistics and request counts
  • Monitor model performance

Testing Your Integration

Test API Compatibility

# Test non-streaming
curl https://your-api.example.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "your-model",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": false
  }'

Verify response includes:

  • ✅ Proper JSON structure
  • choices array with message object
  • usage object with token counts
  • finish_reason field

Test Streaming

# Test streaming
curl https://your-api.example.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "your-model",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

Verify:

  • Content-Type: text/event-stream
  • ✅ Each line starts with data:
  • Final chunk includes usage
  • ✅ Ends with data: [DONE]

Pre-Deployment Checklist

Before going live, verify:

  • Generated provider API key
  • Created config.toml with all models
  • Set environment variables for API keys
  • API accepts POST to /v1/chat/completions
  • API returns proper JSON structure
  • API includes usage object in every response
  • Tested both streaming and non-streaming modes
  • Proxy connects to router successfully
  • Models registered in AiMo Network

Common Issues & Solutions

Missing Usage Data

Problem: Response missing usage field, earnings are zero Solution: Always calculate and include token counts in responses

Incorrect Streaming Format

Problem: Streaming chunks malformed Solution: Each chunk must be valid JSON prefixed with data:

Wrong Content-Type

Problem: Streaming returns application/json Solution: Use text/event-stream for streaming responses

Proxy Connection Failed

Problem: Cannot connect to router Solution: Check API key is valid and network connectivity

Model Not Registered

Problem: Model doesn't appear in network Solution: Check config syntax, restart proxy, view logs

Token Counting Accuracy

Problem: Inaccurate token counts Solution: Use proper tokenizer for your model (e.g., tiktoken for GPT models)

Next Steps