OnlyFans API — Python Quickstart
Make your first OnlyFans API call from Python in a few minutes. All you need is a token and the requests library. Every request goes to https://api.ofapis.com/api/public/v1.
1. Setup
Install requests and load your token from the environment — keep it out of source control:
pip install requests
export OFAPIS_KEY="ofapis_sk_..."
Create the token in the dashboard (start free); details in the authentication guide. Reusing a requests.Session keeps the header in one place and pools connections:
import os, requests
BASE = "https://api.ofapis.com/api/public/v1"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['OFAPIS_KEY']}"
2. Authenticate — GET /me
GET /me returns the connected creator profile and confirms the token works:
me = s.get(f"{BASE}/me")
me.raise_for_status() # raises on 4xx/5xx
print(me.json())
A 200 returns the authenticated creator profile and debits one credit. A failed call is not charged.
3. List chats
chats = s.get(f"{BASE}/chats", params={"limit": 50}).json()
for c in chats.get("data", []):
print(c["id"])
4. Send a message
Wrap writes so a bad token, rate limit, or upstream error is handled cleanly:
def send_message(chat_id, text):
resp = s.post(
f"{BASE}/chats/{chat_id}/messages",
json={"text": text},
)
if resp.status_code == 429:
raise RuntimeError("rate limited — back off and retry")
resp.raise_for_status()
return resp.json() # 200 — delivered, 1 credit spent
send_message("123", "Thanks for subscribing!")
Failed calls — expired session, 429, upstream 5xx — are never charged, so retrying a failure costs nothing. Note that json={...} sets Content-Type: application/json for you.
5. Agencies: scope by account
If you manage several creators, address each by id under scoped routes:
s.get(f"{BASE}/accounts/42/chats")
See agency automation for multi-account patterns.
FAQ
Where do I get a token for the OnlyFans API?
Create an ofapis_sk_... key in the dashboard — start free. Store it as an environment variable and load it at runtime; never commit it to source control.
Is there an official Python SDK?
No dedicated SDK is required — requests is enough. For typed models, point any OpenAPI generator at the spec in the docs and playground to produce a Python client.
How do I handle rate limits in Python?
raise_for_status() will raise on 429, or check resp.status_code directly and back off before retrying. Plan ceilings run from 60 rpm on Free to 500 rpm on Pro — see pricing.
Does a failed request cost a credit?
No. Billing is metered per successful call: one 2xx response equals one credit. Expired sessions, 429s, and upstream 5xx errors are not charged.