The error#
When x-rate-limit-remaining is 0 and x-rate-limit-reset is greater than 0, the client logs Rate limited: {status - remaining/limit - username - errors} and raises HandledError after closing the context until x-rate-limit-reset.
When the error list contains a string that starts with (88) Rate limit exceeded and the remaining header is still above 0, it logs Ban detected: and closes the account with inactive=True. The same HandledError is raised. The comment in the source says this is how a ban is inferred, because there is no direct ban flag.
HandledError is raised with no message. The useful text is the log line.
What triggers it#
A GraphQL response carried those headers or that error prefix. HandledError tells the retry loop to try another account rather than return the body.
How to confirm#
Search the log for Rate limited: or for (88) Rate limit exceeded. inactive=True on the 88 path means that account will not be picked again until you clear it. The header path waits until the reset time and keeps the account.
Fixes#
The pool's response is to rotate accounts. One account that is reset-limited comes back after x-rate-limit-reset. An account marked inactive on code 88 stays out. Adding accounts raises the ceiling. It does not change the per-account headers. NoAccountError is what you get when every account is in one of these states.
SocialScrape#
Profile is GET /v1/twitter/profile. One post is GET /v1/twitter/tweet. A profile's posts are GET /v1/twitter/profile/tweets. These read what X shows logged out.
Failed requests cost 0 credits. New accounts get 100 credits on signup, no card. Suspended accounts come back as removed, unknown ones as not_found.