Skip to content
Notes

What turns an endpoint into an API product

The endpoint is the easy part. Authentication, quota accounting, plans, billing, a dashboard, docs, versioning, error shapes and rate limits are the product.

7 min readAPI productsPlatformDeveloper experience

A working endpoint takes an afternoon. You have data, you expose it over HTTP, it returns JSON, and it is useful.

Then somebody else wants to use it. Now you need to know who they are, how much they may consume, what happens when they exceed it, how they pay, where they see their usage, and what you do the day you need to change the response.

None of that is the endpoint. All of it is the product. Here are the layers, in roughly the order they become urgent.

1. Identity

Nothing else on this list is possible until every request is attributable to an account.

The simplest workable scheme is an API key in a header, checked on each request. Not in the query string, where it lands in access logs and referrer headers. A header like x-api-key is easy to explain, rotate, and curl.

What identity needs from day one: multiple keys per account, so a customer can rotate without downtime and keep staging separate; immediate revocation rather than revocation at the next cache expiry; and a last-used timestamp, which is what lets you tell a customer that the key they are worried about has been idle for six months.

2. Accounting

Once you know who is calling, you have to count, and counting is where the interesting decisions live.

What is the unit? Requests are the obvious choice and often the wrong one, because a lookup and a large aggregation cost you very different amounts. Credits let you price by weight.

What counts? Charging for your own 500 is indefensible. Charging for their malformed 400 is arguable and generates support tickets worth more than the credit. Counting only successful requests is easy to explain, and that beats maximally precise.

When does it reset? Calendar month, rolling thirty days, or billing anniversary. Rolling windows are fairer and harder to explain. Pick one and document it.

Is it correct under concurrency? Ten parallel requests against a balance of one credit must not all succeed. Use an atomic counter, not a read, decide, write sequence.

3. Plans

A plan maps an account to its limits: a free tier, paid tiers, and a custom arrangement for anyone who does not fit the grid.

The free tier is not charity. It is how a developer finds out in ten minutes whether your data fits their problem, without a purchasing conversation. Make it small enough to be uneconomical to abuse and large enough to build a prototype against.

Keep plan definitions as data, not branches in code. When limits live in a table, changing an allocation is an update. When they live in if plan == 'pro', it is a deploy.

4. Billing

The mechanics matter less than the policy, and each question below is a decision before it is an implementation:

  • At 100 percent of quota, hard stop with a 429, or overage at a published rate? A hard stop is safer for the customer and simpler for you.
  • On a failed payment, how long is the grace period and what warning goes out first?
  • Do unused credits roll over? Usually no, and saying so avoids an argument later.
  • Can a customer downgrade mid-cycle, and what happens to their credits?

5. The dashboard

Every question a customer can answer themselves is a support conversation you do not have. The minimum: create, name and revoke keys; usage against the limit and when it resets; recent requests with status codes; plan and invoices.

“How many credits do I have left” is the most common question a metered API receives, and answering it in the interface removes it from your inbox permanently.

6. Documentation

Per-endpoint documentation, meaning each endpoint has a page with parameters, a real request, and a real response body. Not a schema dump.

What separates docs that work: a copy-pasteable curl for every endpoint; real response bodies including the boring fields, so a reader can plan their parsing; every error with the condition that produces it; and the authentication page one click away.

Test it by handing the docs to somebody who has never seen the API and asking them to make an authenticated call. Watch, and do not help. Whatever they get stuck on is the next thing you fix.

7. Error shapes

Errors are part of the interface. Consumers write code against them, so they have to be consistent and machine-readable.

{
  "error": {
    "code": "quota_exceeded",
    "message": "Monthly credit limit reached for this key.",
    "docs": "https://example.com/docs/errors#quota_exceeded"
  }
}

Use the correct HTTP status. Include a stable code whose value never changes wording. Keep the human message for logs and people. And never return a 200 with an error body: it forces every client to parse the body before knowing whether the call worked, and it breaks every generic HTTP client and monitoring tool in existence.

8. Rate limits

A quota is how much you may use this month. A rate limit is how fast. One protects revenue, the other protects your infrastructure from a single enthusiastic loop. Publish both in response headers so a client can pace itself, and return Retry-After on a 429 so it knows when to come back rather than guessing.

9. Versioning

The rule to internalise before your first customer: additive changes are safe, everything else is a new version. Adding a field is fine. Renaming one, removing one, changing a type, or tightening validation are all breaking, however wrong the old behaviour was.

Put the version in the path, keep the previous major working, and announce deprecations with a date. With no version marker at all, you have already decided never to change anything.

A worked example

API Indonesia is our own product and an illustration of the assembled stack. It is live, so everything below can be checked by following the link.

  • Surface: 23 API groups over Indonesian public data, plus 77 MCP tools exposing the same capability to agent runtimes.
  • Identity: a single x-api-key header across every endpoint.
  • Accounting: credit quotas, where only successful requests count.
  • Plans: a free tier, paid tiers, and custom plans.
  • Dashboard: self-serve, for keys, usage, and remaining quota.
  • Documentation: per-endpoint, not one long page.
  • Infrastructure: deployed on the Cloudflare edge network.

Building it made the shape of the list obvious. The data work was the part we expected to be hard, and the endpoints came together quickly. Quota accounting, plan definitions, the dashboard and the documentation took the rest of the time.

Which gives the actual definition. An endpoint becomes a product at the point where somebody who has never met you can sign up, get a key, read the docs, make a call, see their usage, and pay, without a single message in either direction.

Work with us

Have a workflow that fails in a way nobody can describe?

Start with a short fit check. We map the system, name the failure modes, and decide together whether it needs automation, an API product, or a managed integration.

Book a Fit Check