Using X API v2 App-Only Authentication for Public Profile Metrics
App-only bearer tokens let your server read public X profile metrics without user login. This guide covers the lookup endpoint, a worked curl example, caching, and rate-limit caveats.
04 Jan 2026, 14:08 UTC

Your dashboard needs to show a public X profile's follower count. Requiring every visitor to log in with their own X account adds friction and grants more access than you need. The X API v2 user lookup endpoint with app-only authentication removes that friction: your server exchanges a bearer token for public profile data, no user login required.
This approach works because public profile metrics are readable without user context. The trade-off is that app-only tokens are strictly read-only and rate-limited by application, so caching and error handling matter as much as the request itself.
Why app-only auth fits public reads
X API v2 supports two broad authentication modes. User-context OAuth tokens act on behalf of a specific user and are required for actions like posting tweets, following accounts, or reading protected data. App-only authentication uses a bearer token that identifies your application alone.
For reading public fields such as a handle, display name, description, creation date, or follower count, app-only auth is sufficient. It also avoids the security risk of embedding user-context tokens in browsers or mobile binaries, where they can be extracted. Keep the bearer token on your server.
The lookup path and fields
The relevant read path is GET /2/users/by/username/:username. By default it returns only the user ID and handle. To retrieve richer public fields, pass the user.fields query parameter.
Commonly requested fields include created_at, description, and public_metrics. The public_metrics object typically contains followers_count, following_count, tweet_count, and listed_count. The exact set and names are version-sensitive; X has changed field availability and access tiers over time, so treat field names as illustrative until confirmed against current docs.
Worked example: server-side curl
Run this from your backend, not from a browser or mobile client. Replace YOUR_BEARER_TOKEN with your app's token and TARGET_USERNAME with the public handle you want to inspect.
curl -s -H "Authorization: Bearer YOUR_BEARER_TOKEN" \
"https://api.twitter.com/2/users/by/username/TARGET_USERNAME?user.fields=created_at,description,public_metrics"
A successful response returns a JSON object with a data property. Inside, you can read data.id, data.username, and data.public_metrics.followers_count. The exact response body below is illustrative and has not been tested against the live API:
{
"data": {
"id": "123456789",
"username": "example",
"description": "Illustrative profile description.",
"created_at": "2020-01-01T00:00:00.000Z",
"public_metrics": {
"followers_count": 1000,
"following_count": 500,
"tweet_count": 2000,
"listed_count": 10
}
}
}
Parse data.public_metrics.followers_count in your application, but guard against missing keys. If you omit user.fields or request an unsupported field, the response may ignore the field or return an error depending on current API behavior.
Rate limits, caching, and error handling
The endpoint is rate-limited by application and by endpoint. Limits vary by access level, and X has adjusted tiers repeatedly, so you cannot assume a fixed quota. When you exceed the limit, the API returns HTTP 429. Inspect the x-rate-limit-* response headers or the error body to understand the applicable ceiling and reset time.
Because public profile data changes slowly, cache aggressively. A short TTL—such as five to fifteen minutes—is often enough for display purposes. If the API supports conditional requests, an ETag paired with If-None-Match can reduce bandwidth, though you must verify current support for this endpoint.
Handle these status codes explicitly:
401: missing or invalid bearer token.403: your access level does not permit the request.404: the username does not exist, was renamed, or the account was suspended.429: rate limit exceeded.
Do not fall back to scraping X pages when the API fails. Scraping is less stable and may violate the platform's terms.
Limitations and verification
App-only tokens cannot publish tweets, follow users, or access non-public data. Those actions require user-context OAuth with the proper scopes. Also, because X has changed API behavior, scope names, and rate-limit tiers since the v1.1 era, code written for older examples may fail silently or return different fields.
Before deploying, verify three things against the current X developer documentation: the exact endpoint path, the supported user.fields values, and your access level's rate limit. Make a test call with a known public username and confirm the response contains data.username and the requested metrics. Then issue repeated calls until you see a 429 to document the real limit for your app.
Actionable checklist
- Store the bearer token in a server-side secret manager; never hardcode it in client code or public repositories.
- Cache profile responses with a TTL or conditional request headers.
- Log and alert on 401, 403, 404, and 429 responses.
- Rotate tokens immediately if they are exposed.
- Re-check field names and rate limits in the X developer portal before each major release.
App-only authentication is the right tool for public profile reads, but only if you treat the API as a versioned, rate-limited service rather than an open database.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.