Skip to main content

Usage API

The Poe Usage API provides endpoints to monitor your current point balance and retrieve your usage history. These endpoints help you track your consumption and manage your API usage effectively.

Key features:

  • Check your current point balance
  • Retrieve detailed usage history with pagination
  • Monitor usage across all your API calls
  • Track cost per individual query

All Usage API endpoints require authentication using your Poe API key and return data in JSON format.

Authentication

All Usage API endpoints require authentication using your Poe API key in the Authorization header:

Authorization: Bearer YOUR_POE_API_KEY

You can get your API key from https://poe.com/api_key.

Endpoints

Get Current Balance

Retrieve your current point balance, including both plan points and add-on points.

GET https://api.poe.com/usage/current_balance

Headers:

  • Authorization: Bearer YOUR_POE_API_KEY (required)

Response:

{
"current_point_balance": 1500
}

Response Fields:

  • current_point_balance (integer): Your current available points

Example:

curl -X GET "https://api.poe.com/usage/current_balance" \
-H "Authorization: Bearer YOUR_POE_API_KEY"

Get Usage History

Retrieve your usage history with detailed information about each API call. Entries are fetched by creation time, descending, so the most recent usage histories appear first. You can fetch data up to 30 days old.

GET https://api.poe.com/usage/points_history

Headers:

  • Authorization: Bearer YOUR_POE_API_KEY (required)

Query Parameters:

  • limit (integer, optional): Number of entries to return. Maximum 100, default 20.
  • starting_after (string, optional): Pagination cursor. Use the query_id from the last entry of a previous response to get the next page.

Response:

{
"has_more": true,
"length": 20,
"data": [
{
"app_name": "Claude-3.5-Sonnet",
"creation_time": 1704825600,
"query_id": "2Nhd9xBFbLcXEwmNj",
"cost_points": 25
},
{
"app_name": "GPT-4",
"creation_time": 1704825300,
"query_id": "2Nhd9xBFbLcXEwmNk",
"cost_points": 50
}
]
}

Response Fields:

  • has_more (boolean): Whether there are more entries available for pagination
  • length (integer): Number of entries in the current response
  • data (array): Array of usage entries, each containing:
    • bot_name (string): Name of the bot or model used
    • creation_time (integer): Unix timestamp in microseconds when the query was created
    • query_id (string): Unique identifier for the query (used for pagination)
    • cost_points (integer): Number of points consumed by this query
    • usage_type (string): Descriptor for where the points were used
    • chat_name (string): Chat name, if points were used on a chat. Populated if usage_type==Chat
    • App name (string): Canvas app name, if points were used on a canvas app. Populated if usage_type==Canvas App

Examples:

# Get recent usage (default 20 entries)
curl -X GET "https://api.poe.com/usage/points_history" \
-H "Authorization: Bearer YOUR_POE_API_KEY"

# Get specific number of entries
curl -X GET "https://api.poe.com/usage/points_history?limit=50" \
-H "Authorization: Bearer YOUR_POE_API_KEY"

# Paginate results (get next page after specific query_id)
curl -X GET "https://api.poe.com/usage/points_history?starting_after=2Nhd9xBFbLcXEwmNj&limit=20" \
-H "Authorization: Bearer YOUR_POE_API_KEY"

Error Responses

All Usage API endpoints return standard HTTP status codes and JSON error responses:

401 Unauthorized

Missing or invalid API Key:

{ 
"error": {
"message": "Incorrect API key provided. You can find your API key at https://poe.com/api_key.",
"type": "authentication_error",
"code": "invalid_api_key"
}
}

Use Cases

Monitoring and Alerting

import requests

def check_balance_and_alert(api_key, threshold=100):
"""Check balance and alert if below threshold"""
headers = {"Authorization": f"Bearer {api_key}"}

response = requests.get(
"https://api.poe.com/usage/current_balance",
headers=headers
)

balance = response.json()['current_point_balance']

if balance < threshold:
print(f"⚠️ Low balance alert: {balance} points remaining")
return False

print(f"✅ Balance OK: {balance} points")
return True

Usage Analytics

import requests
from collections import defaultdict
from datetime import datetime, timedelta
import time

def analyze_usage_by_model(api_key, days=7):
"""Analyze usage patterns by model over the specified number of days"""
headers = {"Authorization": f"Bearer {api_key}"}

# Calculate cutoff timestamp for filtering (in microseconds)
cutoff_time = (time.time() - (days * 24 * 60 * 60)) * 1_000_000

filtered_entries = []
starting_after = None

# Collect usage data within the time window
while True:
params = {"limit": 100}
if starting_after:
params["starting_after"] = starting_after

response = requests.get(
"https://api.poe.com/usage/points_history",
headers=headers,
params=params
)

data = response.json()

# Filter entries by creation_time (microseconds)
for entry in data['data']:
if entry['creation_time'] >= cutoff_time:
filtered_entries.append(entry)
else:
# Since entries are in descending order, we can stop when we hit older data
break

# Stop if we've hit data older than our cutoff or no more data
if not data['has_more'] or (data['data'] and data['data'][-1]['creation_time'] < cutoff_time):
break

starting_after = data['data'][-1]['query_id']

# Analyze by model
model_usage = defaultdict(lambda: {"calls": 0, "total_cost": 0})

for entry in filtered_entries:
model = entry['app_name']
model_usage[model]['calls'] += 1
model_usage[model]['total_cost'] += entry['cost_points']

# Print results
print(f"Usage statistics for the last {days} days:\n")
for model, stats in sorted(model_usage.items()):
avg_cost = stats['total_cost'] / stats['calls'] if stats['calls'] > 0 else 0
print(f"{model}: {stats['calls']} calls, {stats['total_cost']} total points, {avg_cost:.1f} avg per call")

print(f"\nTotal entries analyzed: {len(filtered_entries)}")
if filtered_entries:
# Convert microseconds to seconds for datetime
oldest = datetime.fromtimestamp(filtered_entries[-1]['creation_time'] / 1_000_000)
newest = datetime.fromtimestamp(filtered_entries[0]['creation_time'] / 1_000_000)
print(f"Date range: {oldest.strftime('%Y-%m-%d')} to {newest.strftime('%Y-%m-%d')}")