Installation
Quick Start
Configuration
from metrifox_sdk import MetrifoxClient
# Option 1: Initialize with API key
client = MetrifoxClient(api_key="your_api_key")
# Option 2: Use environment variable
# Set METRIFOX_API_KEY=your_api_key in your environment
client = MetrifoxClient()
# Option 3: Use the init function
from metrifox_sdk import init
client = init({"api_key": "your_api_key"})
Get your API key from Settings → API Keys in your Metrifox dashboard.
Customer Management
Create a Customer
# Individual customer
customer = client.customers.create({
"customer_key": "user_12345", # Required: unique identifier
"customer_type": "INDIVIDUAL", # Required: "INDIVIDUAL" or "BUSINESS"
"primary_email": "john.doe@example.com", # Required
"first_name": "John",
"last_name": "Doe",
"currency": "USD"
})
# Business customer
customer = client.customers.create({
"customer_key": "company_abc123",
"customer_type": "BUSINESS",
"primary_email": "contact@acmecorp.com",
"legal_name": "ACME Corporation LLC",
"display_name": "ACME Corp",
"website_url": "https://acmecorp.com"
})
Type-Safe Dataclasses
For better type safety and IDE support:
from metrifox_sdk import CustomerCreateRequest
customer_request = CustomerCreateRequest(
customer_key="user_12345",
customer_type="INDIVIDUAL",
primary_email="john.doe@example.com",
first_name="John",
last_name="Doe",
currency="USD"
)
customer = client.customers.create(customer_request)
Update a Customer
response = client.customers.update("user_12345", {
"primary_email": "newemail@example.com",
"first_name": "Jane",
"currency": "EUR"
})
The customer_key cannot be changed after creation.
Get Customer Data
# Get basic customer data
customer = client.customers.get("customer_123")
# Get detailed customer information (includes usage stats, billing info)
details = client.customers.get_details("customer_123")
# List customers with pagination
customers = client.customers.list({
"page": 1,
"per_page": 50
})
# List with filters
customers = client.customers.list({
"search_term": "john@example.com",
"customer_type": "INDIVIDUAL",
"date_created": "2025-09-01"
})
# Check if customer has active subscription
is_active = client.customers.has_active_subscription("customer_123")
Delete a Customer
response = client.customers.delete("customer_123")
Bulk CSV Upload
result = client.customers.upload_csv("/path/to/customers.csv")
print(f"Total: {result['data']['total_customers']}")
print(f"Successful: {result['data']['successful_upload_count']}")
print(f"Failed: {result['data']['failed_upload_count']}")
Usage Tracking & Access Control
Check Feature Access
access = client.usages.check_access({
"feature_key": "premium_feature",
"customer_key": "customer_123"
})
if access['data']['can_access']:
print(f"Access granted. Balance: {access['data']['balance']}")
else:
print("Access denied - upgrade needed")
Record Usage Events
import time
# Simple usage recording
response = client.usages.record_usage({
"customer_key": "customer_123",
"event_name": "api_call",
"event_id": "evt_unique_123", # Required for idempotency
"amount": 1
})
# Advanced usage with metadata
response = client.usages.record_usage({
"customer_key": "customer_123",
"feature_key": "premium_feature",
"event_id": "evt_unique_456",
"amount": 5,
"credit_used": 25,
"timestamp": int(time.time() * 1000), # milliseconds
"metadata": {
"source": "web_app",
"session_id": "sess_xyz"
}
})
Type-Safe Usage Events
from metrifox_sdk import UsageEventRequest
import time
usage_request = UsageEventRequest(
customer_key="customer_123",
event_name="premium_feature",
event_id="evt_unique_123",
amount=1,
timestamp=int(time.time() * 1000),
metadata={"source": "mobile_app"}
)
response = client.usages.record_usage(usage_request)
Complete Usage Example
def use_feature(customer_key, feature_key, event_name):
# 1. Check if customer has access
access = client.usages.check_access({
"feature_key": feature_key,
"customer_key": customer_key
})
if access['data']['can_access']:
# 2. Perform the feature logic
result = perform_feature_logic()
# 3. Record usage after completion
client.usages.record_usage({
"customer_key": customer_key,
"event_name": event_name,
"event_id": f"evt_{result['transaction_id']}",
"amount": result.get('units_used', 1)
})
return {"success": True, "data": result}
else:
return {
"success": False,
"error": "Quota exceeded",
"balance": access['data']['balance']
}
Checkout & Billing
Generate Checkout URL
# Basic checkout URL
checkout_url = client.checkout.url({
"offering_key": "premium_plan"
})
# With billing interval
checkout_url = client.checkout.url({
"offering_key": "premium_plan",
"billing_interval": "monthly"
})
# With customer key for pre-filled checkout
checkout_url = client.checkout.url({
"offering_key": "premium_plan",
"billing_interval": "monthly",
"customer_key": "customer_123"
})
Type-Safe Checkout
from metrifox_sdk import CheckoutConfig
config = CheckoutConfig(
offering_key="premium_plan",
billing_interval="monthly",
customer_key="customer_123"
)
checkout_url = client.checkout.url(config)
Error Handling
from metrifox_sdk import APIError, ConfigurationError
try:
customer = client.customers.get("nonexistent_customer")
except ConfigurationError as e:
print(f"Configuration error: {e}")
except APIError as e:
print(f"API error: {e}")
print(f"Status code: {e.status_code}")
print(f"Response: {e.response_body}")
Framework Integration
Django
# settings.py
from metrifox_sdk import MetrifoxClient
import os
METRIFOX_CLIENT = MetrifoxClient(api_key=os.getenv('METRIFOX_API_KEY'))
# views.py
from django.conf import settings
from django.http import JsonResponse
def premium_feature_view(request):
customer_key = request.user.customer_key
access = settings.METRIFOX_CLIENT.usages.check_access({
"feature_key": "premium_feature",
"customer_key": customer_key
})
if not access['data']['can_access']:
return JsonResponse({
"error": "Access denied",
"balance": access['data']['balance']
}, status=403)
# Process the feature...
settings.METRIFOX_CLIENT.usages.record_usage({
"customer_key": customer_key,
"event_name": "premium_feature_used",
"event_id": f"evt_{request.id}"
})
return JsonResponse({"success": True})
Flask
from flask import Flask, jsonify, request
from metrifox_sdk import MetrifoxClient
import os
app = Flask(__name__)
metrifox_client = MetrifoxClient(api_key=os.getenv('METRIFOX_API_KEY'))
@app.route('/api/premium/<customer_id>', methods=['GET'])
def premium_endpoint(customer_id):
# Check access
access = metrifox_client.usages.check_access({
"feature_key": "premium_api",
"customer_key": customer_id
})
if not access['data']['can_access']:
return jsonify({"error": "Access denied"}), 403
# Process request...
# Record usage
metrifox_client.usages.record_usage({
"customer_key": customer_id,
"event_name": "premium_api_call",
"event_id": f"evt_{request.headers.get('X-Request-ID')}"
})
return jsonify({"data": "premium content"})
FastAPI
from fastapi import FastAPI, HTTPException
from metrifox_sdk import MetrifoxClient
import os
app = FastAPI()
metrifox = MetrifoxClient(api_key=os.getenv('METRIFOX_API_KEY'))
@app.get("/api/feature/{customer_id}")
async def get_premium_feature(customer_id: str):
access = metrifox.usages.check_access({
"feature_key": "premium_feature",
"customer_key": customer_id
})
if not access['data']['can_access']:
raise HTTPException(status_code=403, detail="Access denied")
# Process...
metrifox.usages.record_usage({
"customer_key": customer_id,
"event_name": "feature_accessed",
"event_id": f"evt_{customer_id}_{int(time.time())}"
})
return {"status": "success"}
API Reference
Client Methods
Initialization:
MetrifoxClient(api_key, base_url, web_app_base_url) - Initialize the client
init(config) - Convenience function to initialize the client
Customers Module (client.customers):
create(request) - Create a customer
update(customer_key, request) - Update a customer
get(customer_key) - Get a customer
get_details(customer_key) - Get detailed customer information
list(params) - List customers with pagination and filters
delete(customer_key) - Delete a customer
has_active_subscription(customer_key) - Check for active subscription
upload_csv(file_path) - Upload customers via CSV
Usages Module (client.usages):
check_access(request) - Check feature access
record_usage(request) - Record a usage event
Checkout Module (client.checkout):
url(config) - Generate a checkout URL
Type Definitions
All type definitions are available for import:
from metrifox_sdk import (
CustomerCreateRequest,
CustomerUpdateRequest,
CustomerListRequest,
UsageEventRequest,
AccessCheckRequest,
CheckoutConfig
)
Configuration
Environment Variables
METRIFOX_API_KEY - Your Metrifox API key
Custom URLs
client = MetrifoxClient(
api_key="your_api_key",
base_url="https://custom-api.metrifox.com/api/v1/",
web_app_base_url="https://custom-app.metrifox.com"
)
Default URLs
- Production API:
https://api.metrifox.com/api/v1/
- Meter Service:
https://api-meter.metrifox.com/
- Web App:
https://app.metrifox.com
Requirements
- Python 3.8+
- requests >= 2.31.0
Support
The Python SDK follows Pythonic patterns with type hints, dataclasses, and comprehensive error handling for a great developer experience.