Engagement rate calculator

Measure a Bluesky account or a single post link. The formula is on the page, and where the source gives nothing to divide by, the answer is null.

Engagement rate0.008%mean of 5 posts, vs followers
Followers (divisor)35,094,902author.followers
Interactions14,014likes + comments + shares
estimated_reachnullno view count is published here
Posts with their interactions and engagement rate
PostLikesCommentsSharescomputed.engagement_ratevs followers
Happy opening day of hockey season, NHL fans! Keep up with all 1,344 regular season games…
2026-09-29
73053121null0.003%
If you're in line to vote for @bsky38.com, please stay in line! Polls close in just under…
2026-09-21
76810096null0.003%
I don’t usually meddle on the writing side of Jeopardy!, but tonight I called in a favor …
2026-09-18
10,270157774null0.032%
Less than 4 hours until the #Emmys kick off! You can keep up with all the commentary, win…
2026-09-14
5253138null0.002%
Thanks for being with us here on Bluesky, the official app of sports™️
2026-09-10
326916null0.001%

The API's own computed.engagement_rate is null on 5 of 5: a post from this source carries neither a view count nor its author's follower count, so the API does not guess. The last column applies the same formula with the profile's followers as the divisor (one extra call to bluesky/profile).

The formula

engagement_rate = (likes + comments + shares) / divisor x 100
divisor = engagement.views if it is above 0, else author.followers if it is above 0, else null (so the rate is null)
missing counts among the three count as 0 while at least one is a number; a result above 100 is clamped to 100
estimated_reach = engagement.views when known, else null (observed views, not a model)

Recorded response. A saved answer from the real API. Press Run to fetch a live one.

  • Credits6 when run
  • Calls2
  • API time1,745 ms

The API calls behind this

curl -G "https://api.onekey.dev/v1/bluesky/profile" \
  --data-urlencode "handle=bsky.app" \
  -H "x-api-key: $ONEKEY_KEY"
curl -G "https://api.onekey.dev/v1/bluesky/posts" \
  --data-urlencode "handle=bsky.app" \
  -H "x-api-key: $ONEKEY_KEY"
Raw response
{
  "success": true,
  "data": {
    "author": {
      "id": "did:plc:z72i7hdynmk6r22z27h6tvur",
      "username": "bsky.app",
      "displayName": "Bluesky",
      "followers": 35094902,
      "following": 15,
      "avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka"
    },
    "engagement": {
      "comments": 865
    },
    "content": {
      "text": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app"
    },
    "computed": {
      "language": null
    }
  },
  "metadata": {
    "platform": "bluesky",
    "endpoint": "profile",
    "cached": false,
    "credits_charged": 1
  },
  "error": null
}
{
  "success": true,
  "data": [
    {
      "content": {
        "id": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mwolmfws5k2r",
        "text": "Happy opening day of hockey season, NHL fans! \n\nKeep up with all 1,344 regular season games with this starter pack of hockey writers.",
        "createdAt": "2026-09-29T19:43:14.855Z"
      },
      "author": {
        "id": "did:plc:z72i7hdynmk6r22z27h6tvur",
        "username": "bsky.app",
        "displayName": "Bluesky"
      },
      "engagement": {
        "likes": 730,
        "comments": 53,
        "shares": 121
      },
      "computed": {
        "engagement_rate": null,
        "language": "en"
      }
    },
    {
      "content": {
        "id": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mw2cdr44fc2a",
        "text": "If you're in line to vote for @bsky38.com, please stay in line! Polls close in just under 5 hours.",
        "createdAt": "2026-09-21T18:04:06.128Z"
      },
      "author": {
        "id": "did:plc:z72i7hdynmk6r22z27h6tvur",
        "username": "bsky.app",
        "displayName": "Bluesky"
      },
      "engagement": {
        "likes": 768,
        "comments": 100,
        "shares": 96
      },
      "computed": {
        "engagement_rate": null,
        "language": "en"
      }
    },
    {
      "content": {
        "id": "at://did:plc:zbrhmanjs62oyqywjwdazxz3/app.bsky.feed.post/3mvta262ufs27",
        "text": "I don’t usually meddle on the writing side of Jeopardy!, but tonight I called in a favor for our Bluesky viewers.",
        "createdAt": "2026-09-18T22:34:18.503Z"
      },
      "author": {
        "id": "did:plc:zbrhmanjs62oyqywjwdazxz3",
        "username": "kenjennings.bsky.social",
        "displayName": "Ken Jennings"
      },
      "engagement": {
        "likes": 10270,
        "comments": 157,
        "shares": 774
      },
      "computed": {
        "engagement_rate": null,
        "language": "en"
      }
    },
    {
      "content": {
        "id": "at://did:plc:kwxpje5qog6wwndagwbssatp/app.bsky.feed.post/3mviutosqmk2t",
        "text": "Less than 4 hours until the #Emmys kick off! You can keep up with all the commentary, winners, joy—and, let's face it, disappointment—via our Emmys Watch feed right here on @bsky.app. Pin it now so you don't miss a thing!\n\nbsky.app/profile/avcl...",
        "createdAt": "2026-09-14T19:47:12.655Z"
      },
      "author": {
        "id": "did:plc:kwxpje5qog6wwndagwbssatp",
        "username": "avclub.com",
        "displayName": "The A.V. Club"
      },
      "engagement": {
        "likes": 525,
        "comments": 31,
        "shares": 38
      },
      "computed": {
        "engagement_rate": null,
        "language": "en"
      }
    },
    {
      "content": {
        "id": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mv6jm4auic2g",
        "text": "Thanks for being with us here on Bluesky, the official app of sports™️",
        "createdAt": "2026-09-10T16:59:29.774Z"
      },
      "author": {
        "id": "did:plc:z72i7hdynmk6r22z27h6tvur",
        "username": "bsky.app",
        "displayName": "Bluesky"
      },
      "engagement": {
        "likes": 326,
        "comments": 9,
        "shares": 16
      },
      "computed": {
        "engagement_rate": null,
        "language": "en"
      }
    }
  ],
  "metadata": {
    "platform": "bluesky",
    "endpoint": "posts",
    "cached": false,
    "credits_charged": 5
  },
  "error": null
}
Get 1,000 free creditsRun this on any input with your own key. No card needed.

How it works

Endpoints that declare it add a computed block to every item: engagement_rate is (likes + comments + shares) divided by the view count, or by the author's follower count when there are no views, times 100, and null when neither exists. Nothing is estimated by a model. This page shows that block exactly as the API returned it, next to a second column that applies the same formula with the profile's followers as the divisor, using one extra call to bluesky/profile. Read the rules on the computed block.

Post feeds usually carry no follower count and none of the free sources publishes views, so the API's own rate is often null and estimated_reach stays null too. The page says so instead of inventing a number. Account mode reads the latest 10 posts (1 credit) plus the profile (1 credit); post-link mode resolves a link with URL lookup for 1 credit. The rate is a percentage of followers who interacted, capped at 100, and it is a rough guide: a post can reach people who do not follow the account.