Keeping accounts connected
What each proxy error means, how we re-test and resume on our own, how to check proxy health and data use, and which proxies stay up.
Every connected account syncs through its own proxy, around the clock. When the proxy stops working, background syncing for that account stops with it. This page covers what the errors mean, what happens automatically, and the routes and events you can build on.
What happens when a proxy fails
- One failure never alerts you. A request that fails because of the proxy marks
the account
proxy_errorand schedules a re-test of the saved proxy from our server about 15 minutes later. - A confirmed failure notifies you once. If that re-test also fails, we emit
account.proxy_failedand keep re-testing on a growing schedule: 15, 30, 60, 120 and 240 minutes, then at most every 6 hours. - Recovery is automatic. The first re-test that passes clears the error, resumes
background syncing and emits
account.proxy_recovered. Saving a new proxy withPATCH /accounts/{of_user_id}/proxyschedules a re-test within about a minute.
While an account is in proxy_error, its background jobs (polling, subscriber,
transaction and campaign refreshes) are held, so a dead proxy does not burn through
your proxy plan. A login rejected by the platform is a different state
(login_failed); fixing the proxy does not clear it.
What each error means
The code on connection_error (and on the events below) tells you what went wrong.
The codes are the same ones the API has always returned.
code | What it usually means | What to do |
|---|---|---|
proxy_auth | Your proxy provider refused the login (HTTP 407). Usually the plan is out of data, has expired, or the proxy password was changed. | Check the provider's dashboard: top up, renew or copy the new password. Then test again. |
proxy_connection | The proxy didn't accept a connection: switched off, wrong port, or the provider replaced the IP. | Check host and port with your provider; update the proxy if it changed. |
proxy_timeout | The proxy was too slow to reach the platform: overloaded or rotating onto slow IPs. | Test again; if it keeps timing out, switch to a static ISP or dedicated proxy. |
proxy_reset | The proxy dropped the connection part-way through. | Test again; if it repeats, switch provider or plan. |
proxy_dns | The proxy host name doesn't exist: a typo or a retired host. | Copy the host again from your provider. |
proxy_tls | The proxy interfered with the encrypted connection. | Use a different proxy. |
proxy_blocked | The proxy works, but the platform refuses logins from its IP. | Use a different IP, ideally static residential (ISP) in the creator's country. |
proxy_error | A proxy failure we couldn't pin down. | Run a test to see the exact cause. |
Check health and data use
curl "$BASE/api/crm/$CRM/accounts/$OFUID/proxy/health" -H "X-API-Key: $KEY"{
"success": true,
"of_user_id": "482687148",
"state": "failing",
"code": "proxy_auth",
"title": "Your proxy provider refused the login (407)",
"message": "This usually means the proxy plan is out of data, has expired, or the proxy password was changed.",
"advice": "Check your proxy dashboard, then press Test.",
"failed_at": "2026-10-15T02:53:20",
"next_retest_at": "2026-10-15T03:53:20",
"background_paused": true,
"last_test": { "at": "2026-10-15T03:23:20", "ok": false, "code": "proxy_auth", "latency_ms": null, "of_reachable": null },
"usage": {
"today": { "bytes_up": 1048576, "bytes_down": 9437184, "requests": 214 },
"last_7d": { "bytes_up": 9961472, "bytes_down": 88080384, "requests": 2140 },
"daily": [{ "day": "2026-10-15", "bytes_up": 1048576, "bytes_down": 9437184, "requests": 214 }]
},
"recommendation": { "kind": "static_isp_unlimited", "text": "…" }
}state is ok, failing, untested or no_proxy. The proxy itself is never
returned. Data figures are counted from request and response sizes plus an estimate
of connection overhead, so your provider's figure may be slightly higher.
The account list (GET /accounts) carries the same summary per account:
proxy_state, proxy_failed_at, proxy_next_retest_at, proxy_bytes_today,
proxy_bytes_7d, and connection_error.next_retest_at, auto_retesting and
background_paused.
For every account at once:
curl "$BASE/api/crm/$CRM/proxy/usage?days=7" -H "X-API-Key: $KEY"Test the saved proxy
curl -X POST "$BASE/api/crm/$CRM/accounts/$OFUID/proxy/test" -H "X-API-Key: $KEY"{ "success": true, "ok": true, "code": null, "title": null, "message": null,
"latency_ms": 231, "of_reachable": true, "resumed": true }This tests the proxy already saved on the account, from our server, and sends nothing
in the body. When the account was in a proxy error and the test passes, the error
clears and syncing resumes straight away (resumed: true). Limited to 6 tests per
minute. To test a proxy you haven't saved yet, use POST /proxy/test with
{"proxy": "…"} as described in Proxies.
Events
event_type | When | Delivered to |
|---|---|---|
account.proxy_failed | A re-test confirms the proxy is failing (once per outage) | SSE, webhooks, automations, Telegram |
account.proxy_recovered | The proxy works again and syncing has resumed | SSE, webhooks, automations, Telegram |
account.proxy_tested | Someone pressed Test (or called the test route) | SSE only |
{
"of_user_id": "482687148",
"username": "creatorname",
"platform": "onlyfans",
"code": "proxy_auth",
"title": "Your proxy provider refused the login (407)",
"message": "This usually means the proxy plan is out of data, has expired, or the proxy password was changed.",
"failed_at": "2026-10-15T02:53:20",
"recovered_at": null,
"downtime_seconds": null,
"retest_count": 1,
"link": "/dashboard/accounts/482687148"
}On account.proxy_recovered, recovered_at and downtime_seconds are filled in.
Subscribe with "event_types": ["account.proxy_failed", "account.proxy_recovered"]
on a webhook, or * for everything.
Choosing a proxy that stays up
Most failures we see are pay-per-GB plans running out of data, and rotating proxies changing IP mid-session.
- Unlimited data. Static ISP and dedicated proxies are usually sold per IP with
unlimited data. A per-GB residential plan runs dry, and then every request gets a
407. Use the
usagefigures above to size a plan if you must pay per GB. - Sticky sessions. If your provider rotates IPs, use a sticky (session) port that holds one IP for as long as possible, ideally 24 hours or more. An IP that changes on every request looks like a new login each time.
- One proxy per account, in the creator's own country, and keep the same region when you replace it.