OnlyFans API with PHP
ofapis is a plain REST API with Bearer auth, so you can call the OnlyFans API from PHP with the built-in cURL extension or Guzzle — no SDK required. This quickstart takes you from token to a sent message. Every request goes to https://api.ofapis.com/api/public/v1.
1. Get a token
Create an ofapis_sk_... token in the dashboard (start free) and keep it server-side — never ship it to a browser. Load it from the environment rather than hard-coding it. Details in the authentication guide.
2. Install Guzzle (optional)
The cURL extension ships with PHP, so the examples below run without dependencies. For a nicer client, add Guzzle with Composer:
composer require guzzlehttp/guzzle
3. Verify the token — GET /me
Set the Authorization header on every call. GET /me returns the connected creator profile and confirms the token works:
<?php
$base = "https://api.ofapis.com/api/public/v1";
$token = getenv("OFAPIS_KEY");
$ch = curl_init("$base/me");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("ofapis /me failed: HTTP $status — $response");
}
$me = json_decode($response, true);
echo $me["username"] ?? "connected", PHP_EOL;
4. List chats
<?php
$ch = curl_init("$base/chats?limit=50");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($data["data"] ?? [] as $chat) {
echo $chat["id"], PHP_EOL;
}
5. Send a message — Guzzle
Guzzle makes error handling explicit: a non-2xx status throws, so wrap the call in try/catch.
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client(["base_uri" => "$base/"]);
try {
$res = $client->post("chats/123/messages", [
"headers" => ["Authorization" => "Bearer $token"],
"json" => ["text" => "Thanks for subscribing!"],
]);
echo $res->getStatusCode(); // 200
} catch (RequestException $e) {
// 401 bad token, 429 rate limit, 5xx upstream — none of these are charged
$code = $e->getResponse()?->getStatusCode();
error_log("send failed: HTTP $code");
}
A 200 means the message was delivered and one credit was spent. Failed calls — expired session, rate limit, upstream error — are never charged, so retrying a failure costs nothing.
Agencies: scope by account
Managing several creators? Address each by id under scoped routes, e.g. GET /accounts/42/chats and POST /accounts/42/chats/123/messages. See agency automation.
FAQ
Do I need a PHP SDK for the OnlyFans API?
No. ofapis is a standard REST API, so the built-in cURL extension or Guzzle is enough. If you want typed models, point any OpenAPI generator at the spec at /docs.
How do I handle rate limits in PHP?
Watch for HTTP 429 and back off before retrying; limits run from 60 rpm on Free up to 500 rpm on Pro. See pricing for your plan's ceiling.
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.
Which PHP version should I use?
PHP 7.4+ works with cURL and Guzzle, but PHP 8.0+ is recommended for the nullsafe operator (?->) used in the error-handling example above.
Next steps
- Messaging API reference
- Subscribers API
- Other languages: Node · Python · Go