Track which SDK versions your customers are on

Look at sdk_version on api_request events. What % are on latest vs N-1 vs older? Critical for the 'when can we deprecate?' conversation.

Published

difficulty beginner · time to value 1 minute · tools used 2

Just say this

Look at the sdk_version property of api_request events. What % of distinct customers are on the latest vs N-1 vs N-2 or older?

Why this matters

Deprecating an old SDK version is easy — git rm, ship a note. Deprecating without breaking 30% of your customers is the hard part. Without per-version distribution data you’re guessing whether the upgrade-or-fail email goes to 12 customers or 1,200.

Most teams find out only after the deprecation breaks production for a large account. That call is uniquely terrible because it’s 100% preventable — the data was always there in your API logs, you just never queried it.

Agentry treats SDK version as a property on api_request events. One HogQL pass gives you the distribution + customer list per version. The deprecation conversation becomes specific instead of “let’s wait another quarter to be safe.”

What you get

  • Distribution of distinct customers per SDK version
  • Same distribution by request volume (sometimes one customer on the old SDK is 90% of your old-SDK traffic)
  • A clear list of “customers still on N-2 or older” — your outbound list

Walk through it

You

Look at the sdk_version property of api_request events. What % of distinct customers are on the latest vs N-1 vs N-2 or older?

Agent

Distinct customers per version, then a rollup.

agentry_analytics_query {
  project_id: "default",
  query: "
    select
      properties.sdk_version as ver,
      count(distinct properties.customer_id) as customers,
      count() as requests
    from events
    where event = 'api_request' and timestamp > now() - interval 30 day
    group by ver
    order by ver desc
  "
}
{
  "rows": [
    { "ver": "3.4.0", "customers":  142, "requests":  4200000 },
    { "ver": "3.3.2", "customers":  610, "requests": 38400000 },
    { "ver": "3.3.1", "customers":  240, "requests":  6800000 },
    { "ver": "3.3.0", "customers":  120, "requests":  2400000 },
    { "ver": "3.2.4", "customers":   42, "requests":   180000 },
    { "ver": "3.1.9", "customers":   18, "requests":   840000 },
    { "ver": "2.8.1", "customers":    3, "requests":  2200000 }
  ]
}
Agent

Two ways to slice the picture:

By customer count:

VersionCustomers% of customers
3.4.0 (latest)14211.7%
3.3.x (N-1)97080.1%
3.2.x (N-2)423.5%
3.1.x181.5%
2.x30.2%

By request volume: (this is where it gets interesting)

VersionRequests% of traffic
3.4.04.2M7.6%
3.3.x47.6M86.6%
3.2.x0.18M0.3%
3.1.x0.84M1.5%
2.x2.2M4.0% ★

Notable: 3 customers on v2.8.1 are 4% of your total API traffic (2.2M requests/30d). One of them is presumably one of your big enterprise accounts that never upgraded. Deprecating 2.x without warning would be a Tier-1 incident.

Recommended:

  1. Safe to deprecate 3.1.x and older (~63 customers, mostly low-volume). Send a 90-day notice.
  2. Find who the v2.8.1 customers are — they need an account-manager-led upgrade conversation, not an email blast.
  3. Publish the table so the API team can pull it up at every release planning.
agentry_publish_query {
  recipe_id: "raw_hogql",
  description: "SDK version distribution (30d)",
  params: { query: "<same query above>" }
}
{ "publication_id": "pub_sdk_v", "public_url": "https://agentry.sh/q/pub_sdk_v?key=agp_…" }
agentry_analytics_query {
  project_id: "default",
  query: "
    select
      properties.customer_id as customer,
      sum(case when properties.sdk_version = '2.8.1' then 1 else 0 end) as v2_calls,
      sum(case when properties.sdk_version like '3.%' then 1 else 0 end) as v3_calls
    from events
    where event = 'api_request' and timestamp > now() - interval 30 day
    group by customer
    having v2_calls > 0
    order by v2_calls desc
  "
}
{
  "rows": [
    { "customer": "wayne_ent", "v2_calls": 1840000, "v3_calls": 0 },
    { "customer": "umbrella_co", "v2_calls": 240000, "v3_calls": 4810000 },
    { "customer": "stark_legacy", "v2_calls": 120000, "v3_calls": 0 }
  ]
}
Agent

Interesting: umbrella_co is mostly on v3 (4.8M v3 calls) but still has 240k v2 calls — probably one stale microservice they forgot about. Easy ask for them to find and update.

wayne_ent and stark_legacy are 100% on v2. These are the conversations that need an AM, not a blast email.

The output

SDK version distribution (30d)

Version    Customers    %        Requests       %       Notes
─────────────────────────────────────────────────────────────────
3.4.0       142         11.7%    4,200,000     7.6%    latest
3.3.2       610         50.4%   38,400,000    69.9%    N-1 (stable)
3.3.1       240         19.8%    6,800,000    12.4%    N-1
3.3.0       120          9.9%    2,400,000     4.4%    N-1
3.2.4        42          3.5%      180,000     0.3%    N-2 (deprecate)
3.1.9        18          1.5%      840,000     1.5%    deprecate
2.8.1         3          0.2%    2,200,000     4.0%    ★ enterprise — AM-led

Deprecation plan:
  Tier 1: 3.1.x and older (≤63 customers, low volume)
    → 90-day email notice
    → Hard sunset at +90 days
  Tier 2: 2.8.1 customers (3 customers, HIGH volume)
    → AM-led upgrade
    → wayne_ent and stark_legacy need migration help
    → umbrella_co has a stray service (240k calls) to track down

Public dashboard:
  https://agentry.sh/q/pub_sdk_v?key=agp_xxx

Setting it up

Tag every api_request event with the SDK version the client sent (or the absence of a version, which usually means “raw HTTP / curl”):

// API middleware
const sdkVersion =
  c.req.header("x-sdk-version") ??     // SDK convention
  c.req.header("user-agent")?.match(/myapi-sdk-js\/([\d.]+)/)?.[1] ??
  "unknown";

fetch(`https://api.agentry.sh/v1/analytics/${PROJECT_ID}/`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${env.AGENTRY_DSN}`,
    "Content-Type": "application/json",
    "User-Agent": "myapi-edge/1.0",  // REQUIRED — Cloudflare 403s default UAs
  },
  body: JSON.stringify({
    event: "api_request",
    distinct_id: customer.id,
    properties: {
      customer_id: customer.id,
      sdk_version: sdkVersion,
      sdk_language: c.req.header("x-sdk-language") ?? "unknown",
      endpoint: c.req.routePath,
    },
  }),
}).catch(() => {});

If your SDK doesn’t send a version header today, ship a version that does in the next release. Old clients will continue to show as “unknown” — that group itself is informative (“how many requests are coming from people who don’t even use our SDK?”).

Variations

  • “Same query split by sdk_language — what % of traffic is from the Python SDK vs JS vs Go?”
  • “For each old SDK version, which API endpoints do those clients hit? Tells me what to keep backward-compatible on the API surface.”
  • “Error rate per SDK version — old versions sometimes drive higher error rates because they don’t handle new error codes.”
  • “Day-over-day trend on v3.4.0 adoption — is the latest release picking up users at expected rate?”

Try this recipe in your own agent.

Paste the prompt above into your agent. It'll set up Agentry against your data, then run the recipe and show you the real output.

Install https://agentry.sh/agentry.md and set it up