Python requests 2.x

OnlyFans API Python SDK

Full Python integration for the OnlyFans API using the requests library. Revenue tracking, fan analytics, payout reconciliation, and messaging automation — all in clean, idiomatic Python.

Installation

The OnlyFans API Python SDK uses the requests library — the most widely used HTTP client in the Python ecosystem. No other dependencies are required. Python 3.8 or later is recommended.

Terminal pip
# Install the requests library
pip install requests
Recommended: Use a virtual environment (python -m venv .venv) to keep dependencies isolated per project.

Configuration

Create a shared ofapi.py module in your project. This sets up the base URL, injects the X-API-Key header on every request, and provides a single ofapi() function all your scripts import.

ofapi.py Python
# ofapi.py — shared client config
import requests
import os

BASE_URL = "http://157.180.79.226:4024/api/v1/onlyfans"

HEADERS = {
    "X-API-Key": os.environ["OFAPI_KEY"],
    "Content-Type": "application/json",
}

def ofapi(path, method="GET", **kwargs):
    url = f"{BASE_URL}{path}"
    resp = requests.request(method, url, headers=HEADERS, **kwargs)
    resp.raise_for_status()
    return resp.json()
.env Shell
OFAPI_KEY=your_api_key_here

Get Revenue Statistics

Pull a complete earnings breakdown for any creator on your account — subscriptions, tips, PPV messages, PPV posts, referrals, and chargebacks. Use this to build P&L dashboards and automate commission calculations.

GET /models/:id/statistics/overview

revenue.py Python
from ofapi import ofapi

def get_revenue_stats(creator_id):
    data = ofapi(f"/models/{creator_id}/statistics/overview")
    return data

stats = get_revenue_stats("creator_abc123")
print(f"Total earnings: ${stats['totalEarned']}")
print(f"Subscriptions:  ${stats['subscriptions']}")
print(f"Tips:           ${stats['tips']}")
print(f"PPV:            ${stats['ppv_messages'] + stats['ppv_posts']}")
Response JSON
{
  "creator_id": "creator_abc123",
  "totalEarned": 12847.50,
  "subscriptions": 4200.00,
  "tips": 3100.25,
  "ppv_messages": 3847.00,
  "ppv_posts": 1200.25,
  "referrals": 500.00,
  "chargebacks": 0.00,
  "period": "all_time",
  "currency": "USD"
}

List Top Fans

Retrieve a ranked list of fans sorted by total lifetime spend. Use this to power VIP identification, prioritize outreach sequences, and flag high-value fans at churn risk.

GET /models/:id/stats/fans/top

top_fans.py Python
from ofapi import ofapi

def get_top_fans(creator_id, limit=10):
    data = ofapi(
        f"/models/{creator_id}/stats/fans/top",
        params={"limit": limit}
    )
    return data["fans"]

fans = get_top_fans("creator_abc123", limit=5)
for i, fan in enumerate(fans, 1):
    print(f"#{i} {fan['username']} — ${fan['total_spent']}")
Response JSON
{
  "fans": [
    {
      "user_id": "fan_001",
      "username": "bigspender99",
      "total_spent": 3420.00,
      "tips_total": 1800.00,
      "ppv_total": 1420.00,
      "subscriptions_total": 200.00,
      "subscriber_since": "2024-03-15",
      "is_active": true
    }
  ],
  "total_count": 847
}

Track Payouts

Retrieve full payout transaction history for a creator. Paginate through all records to reconcile earnings, automate agency commission splits, and build payout forecasting tools.

GET /models/:id/payouts/transactions

payouts.py Python
from ofapi import ofapi
from datetime import datetime

def get_payouts(creator_id, page=1, limit=20):
    data = ofapi(
        f"/models/{creator_id}/payouts/transactions",
        params={"page": page, "limit": limit}
    )
    return data

result = get_payouts("creator_abc123")
now = datetime.now()

# Sum payouts for the current month
this_month = [
    t for t in result["transactions"]
    if datetime.fromisoformat(t["date"].replace("Z", "+00:00")).month == now.month
]
total = sum(t["amount"] for t in this_month)
print(f"Paid out this month: ${total}")
Response JSON
{
  "transactions": [
    {
      "id": "txn_8f3a91",
      "amount": 3240.00,
      "status": "completed",
      "method": "bank_transfer",
      "date": "2026-03-03T09:00:00Z",
      "period_start": "2026-02-24",
      "period_end": "2026-03-02"
    }
  ],
  "page": 1,
  "total_pages": 8
}

Get Subscriber Data

Pull ranked subscriber data sorted by total lifetime spend. Combine with fan behavior signals to identify high-LTV profiles and build automated retention and re-engagement workflows.

GET /models/:id/subscribers/top

subscribers.py Python
from ofapi import ofapi

def get_top_subscribers(creator_id, limit=20):
    data = ofapi(
        f"/models/{creator_id}/subscribers/top",
        params={"limit": limit}
    )
    return data["subscribers"]

subs = get_top_subscribers("creator_abc123")

# Flag high-value subs with no recent activity
from datetime import datetime, timezone, timedelta
cutoff = datetime.now(timezone.utc) - timedelta(days=14)

at_risk = [
    s for s in subs
    if s["total_spent"] > 200
    and datetime.fromisoformat(
        s["last_purchase_at"].replace("Z", "+00:00")
    ) < cutoff
]
print(f"{len(at_risk)} high-value subs at churn risk")
Response JSON
{
  "subscribers": [
    {
      "user_id": "fan_001",
      "username": "bigspender99",
      "total_spent": 3420.00,
      "subscription_price": 14.99,
      "subscribed_since": "2024-03-15",
      "last_purchase_at": "2026-03-01T14:22:10Z",
      "rebill_count": 24,
      "is_active": true
    }
  ],
  "total": 847
}

Send a Message

Send a direct message to a specific fan — optionally with a PPV price lock and media attachments. Use this to power chatting team automation, drip sequences, mass PPV blasts, and re-engagement campaigns.

POST /messages/send

send_message.py Python
from ofapi import ofapi

def send_message(creator_id, fan_id, text, ppv_price=None, media_ids=None):
    body = {
        "creator_id": creator_id,
        "fan_id": fan_id,
        "text": text,
    }
    if ppv_price is not None:
        body["ppv_price"] = ppv_price
    if media_ids:
        body["media_ids"] = media_ids

    result = ofapi("/messages/send", method="POST", json=body)
    return result

# Send a PPV re-engagement message
result = send_message(
    creator_id="creator_abc123",
    fan_id="fan_001",
    text="Hey! Made something special just for you 🔥",
    ppv_price=12,
    media_ids=["media_xyz789"],
)
print(f"Message sent: {result['message_id']}")
Response JSON
{
  "message_id": "msg_4d9f2a",
  "status": "sent",
  "creator_id": "creator_abc123",
  "fan_id": "fan_001",
  "ppv_price": 12,
  "has_media": true,
  "sent_at": "2026-03-05T11:42:00Z"
}

Error Handling

The raise_for_status() call in the shared client raises a requests.exceptions.HTTPError for any 4xx or 5xx response. Catch it and branch on e.response.status_code for retries, alerting, and graceful degradation.

error_handling.py Python
import requests
from ofapi import ofapi

try:
    stats = ofapi(f"/models/creator_abc123/statistics/overview")
except requests.exceptions.HTTPError as e:
    status = e.response.status_code
    if status == 401:
        print("Invalid API key — check OFAPI_KEY env var")
    elif status == 403:
        print("Creator not linked to your account")
    elif status == 429:
        retry_after = e.response.headers.get("Retry-After", "5")
        print(f"Rate limited — retry after {retry_after}s")
    else:
        print(f"API error {status}: {e.response.text}")
except requests.exceptions.ConnectionError:
    print("Network error — API unreachable")
Status Meaning Action
200 OK Parse and use the response body
400 Bad Request Check required params; read message
401 Unauthorized Verify X-API-Key header is present and correct
403 Forbidden Creator not linked to your API account
429 Rate Limited Back off using Retry-After header
500 Server Error Retry with exponential backoff; contact support