Tag: ai agents
An AI Agent Flight Recorder Belongs in One Portable File, the Way HAR Did It for HTTP
An agent edits the wrong config file, then spends forty minutes trying to repair its own repair. The user files a bug with a screenshot of the last message. The maintainer asks for logs, and the logs live in four places: the provider’s usage page, the tool server’s stdout, the framework’s debug output, and a terminal scrollback that closed with the window. Nobody can say what the agent saw on turn six.
MCP Tool Calls Are Plain HTTP Now: Route Them With a Small Proxy Before Buying a Gateway
A platform team runs four MCP servers for its coding agents: GitHub, internal docs search, a read-only Postgres server and the ticketing system. Someone wants per-tool rate limits and a log of which agent called what, so a gateway evaluation goes on the calendar. Nobody has asked the cheaper question yet, which is how much of that the reverse proxy they already run can handle.
Since July, quite a lot. The 2026-07-28 revision made MCP stateless at the protocol layer: the initialize handshake is gone, the Mcp-Session-Id header is gone, and every request carries its own protocol version, client info and capabilities. Two new headers, Mcp-Method and Mcp-Name, copy the JSON-RPC method and (for a tool call) the tool name out of the body and into headers, where proxies already look. Without sessions, an MCP server behaves much like any other HTTP API, which is why the difference between an API and MCP now comes down to who reads the docs. Before the revision, a proxy needed a body-parsing module to learn which tool was being called, and usually session affinity to keep each client on the backend holding its session. Now stock nginx covers the basics:
Most MCP Token Waste Is in Tool Results: Put a Deterministic Reducer Between Server and Model
An agent calls a code-search tool and gets back a hundred hits. Each hit carries dozens of fields: node IDs, a URL for every related resource, avatar links, permission flags. The model needed three of them, a repo, a path and a snippet. The rest now sits in the context window for the remainder of the session, and the model reads past it on every later turn.
Tool definitions get most of the attention in agent token costs, and they’ve earned it. A server that exposes 150 tools puts 150 schemas in front of the model on every turn. Results are the other half of the bill, and they have fewer standard answers. An ordinary API client ignores the fields it doesn’t use, and ignoring is free. A model pays to read every token it’s handed.
Record an Agent's MCP Traffic Once, Then Replay It in CI Without Servers or Credentials
Your agent test passes on your laptop and fails in CI. The laptop has a token for the issue tracker’s MCP server; CI doesn’t, and shouldn’t. Even with a token, the tracker listed three open bugs yesterday and lists four today, so the agent’s summary changes and the assertion on it breaks.
Web developers dealt with this years ago. VCR (Ruby), Polly.js, Betamax and go-vcr record real HTTP responses into a file the first time a test runs, then serve them from that file on every run after. The file is called a cassette. MCP needs the same thing: a proxy that sits between an agent and its MCP servers, writes every exchange into one cassette, and plays it back later with no server, no credentials and no network. mcprec below is an illustrative name for a tool you’d have to build.
The New MCP Spec Caches Tool Lists but Not Tool Calls, and a Caching Proxy Fills the Gap
An agent works through a ticket and asks a docs-search tool the same question on turn 3, again on turn 14, and again the next morning in a fresh session. Each repeat costs a charge against the upstream’s rate limit and a wait with the model idle, for an answer that never changed. Agents retry after errors and start every session by looking up what the last one already knew.
Orkes Raises $60M to Bring Production-Grade AI Orchestration to Enterprise Developers
Orkes, the workflow and agent orchestration platform founded by the original engineers behind Netflix’s microservices infrastructure, has closed a $60 million Series B round led by AVP, with participation from Prosperity7 Ventures, Nexus Venture Partners, Battery Ventures, and Vertex Ventures US. The raise signals growing enterprise demand for orchestration infrastructure that can take AI workloads from prototype to production without falling apart.
The company’s foundation is Conductor, an open-source orchestration engine originated at Netflix in 2016 and still actively maintained by Orkes. Netflix’s own internal usage of Conductor has grown fivefold in recent months, and the project counts developers at JP Morgan Chase, Tesla, Atlassian, Oracle, American Express, and GE Healthcare among its users. Since its $20 million Series A in 2024, Orkes has tripled its paying customer base and built a developer community in the hundreds of thousands.
Form.io Launches MCP Server and Agentic Coding Toolset for Governed Enterprise AI Development
Form.io has released an MCP Server, Skills library, and Agentic Coding Plugin designed to bring schema-governed infrastructure to AI coding environments — extending its existing Universal Agent Gateway into the build-time layer. The toolset targets enterprise development teams using agentic coding tools such as Claude Code, Cursor, and Windsurf, where the default outcome is speed without standardization.
The problem Form.io is addressing is real and increasingly visible. As agentic coding accelerates across large organizations, applications generated by independent teams diverge in architecture, data handling, and compliance posture. Each agent makes its own decisions; five teams produce five incompatible implementations of the same solution. The efficiency gains nominally promised by agentic coding are offset by the governance overhead required to manage the fragmentation afterward.
Tag: api design
Idempotency Keys: How One Header Stops a Retry From Charging a Customer Twice
A client sends a POST to create a payment. The server charges the card, writes the record, and starts sending the response. Then the connection drops. The client sees a timeout and has no way to tell whether the charge happened. If it retries, the customer may pay twice. If it doesn’t, the order may never complete.
Every API that creates or changes something over a network has this problem. GET, PUT and DELETE are idempotent by definition in HTTP, so repeating them is safe. POST and PATCH aren’t. The fix most payment APIs settled on is a client-generated key sent with the request, which the server uses to recognize a retry and hand back the original answer instead of doing the work again.
Infer Your API's Real Contract From Traffic, Then Diff It Against the Docs
Your OpenAPI file marks shipping_address as required on GET /orders/{id}. After Tuesday’s deploy, about one response in 300 leaves it out, because a new code path for orders created by the import job skips the field. The docs still say required. The tests still pass, since nobody wrote one for import-job orders. A client with a strict deserializer starts throwing on 0.3% of order pages, and the first report you get is “sometimes the order screen is blank”.
Mapping an Unfamiliar API by Following the IDs Between Its Endpoints
You inherit an integration with a partner API that has 140 endpoints, documented in alphabetical order. GET /accounts sits next to GET /adjustments, and POST /refunds is a long scroll away from the GET /charges/{id} it depends on. Nobody wrote down that a refund hangs off a charge, which hangs off an order, which may or may not have a customer. You find out the slow way: call an endpoint, copy an ID out of the response, paste it into the next call, and keep a diagram in a notebook that’s out of date by Thursday.
Trimming 100 KB API Responses to the Five Fields Your Client Uses, at the Proxy
Take a mobile screen that lists orders: a customer name, a status, a total, a date. The endpoint behind it returns 100 KB for one page, because the vendor’s schema carries about sixty fields per order, plus nested addresses, hypermedia links and an audit trail. The phone downloads all of it over whatever connection it has, parses all of it, and keeps five fields. You can’t change the vendor’s API. You can change what reaches the phone.
Audit an API Field's Completeness Before You Build a Feature on It
An API’s documentation lists the fields a record can have. It rarely tells you how many records actually have them. Those are different numbers, and on open data APIs the gap is often enormous.
The failure looks like this. You read the schema, spot a field that would make a great feature, build the feature, and then discover the field is populated on four percent of the data. By then the feature is written and the pitch has been made.
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Every Accident in Your API Becomes a Contract
You don’t get to decide which parts of your API are the API. Your users decide that, and they decide it by accident.
We removed a field once. It was called legacy_status, it duplicated a value that already existed under a better name, and it had been marked deprecated in the docs for a year and a half. Nobody read it. We checked the logs, checked the support tickets, checked with the two biggest accounts, and shipped the removal on a Tuesday.
Breaking Changes: How to Avoid Shipping Them and What to Do When You Must
A breaking change is any modification to an API that requires consumers to update their integration to continue functioning. The definition is straightforward. The practice of avoiding breaking changes while evolving an API requires engineering discipline that most teams underestimate until they have shipped a breaking change to a production API and experienced the resulting incident response.
The instinct to avoid defining something as a breaking change is strong. Removing a field that is not documented is tempting to classify as cleanup rather than a breaking change. Changing an error code from 400 to 422 for a validation failure seems like a trivial semantic correction. Adding a required field to a request body seems like a new feature rather than a breaking change. Each of these reclassifications is wrong, and each produces consumers whose integrations fail after the change.
SDK Design: Making Your API Easy to Use Is Not the Same as Making It Easy to Build
An SDK — a software development kit providing a client library for an API — is the interface through which most developers interact with a third-party API in production. The quality of the SDK determines the quality of the integration experience more than the quality of the underlying API, because most developers never interact with the API directly. They interact with the SDK that wraps it.
The gap between a good API and a good SDK is wide and frequently underestimated. A well-designed API with a poorly designed SDK produces frustrated developers who waste time on integration mechanics instead of building their application. A mediocre API with a well-designed SDK produces developers who build successfully and attribute the quality of their experience to the API provider rather than the SDK.
API Testing Strategies That Catch the Problems Unit Tests Miss
Unit tests verify that individual functions behave correctly in isolation. They run fast, catch regressions close to where they are introduced, and document expected behavior at the code level. They do not verify that the API endpoints exposed to consumers behave according to the documented contract, that changes in one service do not break the consumers that depend on it, or that the system behaves correctly under the conditions that production traffic creates.
Pagination Strategies for Large Datasets and Why Offset Pagination Fails
Offset pagination — the pattern where a consumer requests a page by specifying how many records to skip — is the default choice for most APIs because it maps naturally to SQL’s LIMIT and OFFSET clauses and allows consumers to request any page directly by number. It is also the pagination strategy that fails most visibly at scale and produces the most confusing behavior when underlying data changes between page requests.
HTTP Status Codes Are Being Used Wrong and It Is Your Problem Too
The HTTP status code specification is 30 years old, fully documented, and widely misimplemented. The misimplementation is not ignorance — most API developers know that 200 means success and 404 means not found. It is the edge cases where the correct status code requires a moment of thought that the wrong choice gets made, and the wrong choice gets propagated to every consumer who must now handle an error that does not mean what the specification says it means.
Webhooks vs Polling: The Decision Most Teams Get Backwards
The polling versus webhooks decision is frequently made on the basis of what the API provider finds easiest to implement rather than what serves consumers best. Polling is easier to provide — it requires no additional infrastructure beyond the existing API endpoints. Webhooks require the provider to maintain delivery infrastructure, handle failures, implement retry logic, and manage consumer endpoint registration. The provider’s preference for polling is understandable. For the consumers who pay the operational cost of polling, it is not a neutral choice.
API Versioning Strategies That Don't Break Your Consumers
API versioning is the discipline that separates API providers who have operated public APIs for several years from those who have not. Early-stage API design focuses on what the API should do. Mature API design focuses on how the API will evolve without breaking the consumers who have built on top of it. The difference in focus reflects a difference in experience with the consequences of getting it wrong.
Breaking changes are changes that require consumers to modify their integration to continue functioning. They include removing endpoints, removing fields from responses, changing field names, changing data types, changing authentication requirements, and changing the semantics of existing parameters. Every team that has shipped a breaking change to a public API without a migration path has received the same feedback from affected consumers, expressed with varying degrees of professionalism.
REST vs GraphQL vs gRPC: The Honest Comparison
The choice between REST, GraphQL, and gRPC is treated in most discussions as a question of technical preference when it is primarily a question of context. Each protocol was designed for a specific problem space. Each performs well in that space and poorly outside it. The comparison articles that declare one winner across all use cases are either selling something or have not operated all three at production scale.
REST’s dominance in public API design is not accidental. The constraints it imposes — statelessness, uniform interface, resource-based addressing — map naturally to HTTP’s caching infrastructure, client library ecosystems, and the mental model that most developers already carry from web development. A REST API can be consumed with curl. It can be documented with OpenAPI. It can be cached at the edge. These properties have real operational value that architectural elegance alone cannot purchase.
Tag: api gateways
MCP Tool Calls Are Plain HTTP Now: Route Them With a Small Proxy Before Buying a Gateway
A platform team runs four MCP servers for its coding agents: GitHub, internal docs search, a read-only Postgres server and the ticketing system. Someone wants per-tool rate limits and a log of which agent called what, so a gateway evaluation goes on the calendar. Nobody has asked the cheaper question yet, which is how much of that the reverse proxy they already run can handle.
Since July, quite a lot. The 2026-07-28 revision made MCP stateless at the protocol layer: the initialize handshake is gone, the Mcp-Session-Id header is gone, and every request carries its own protocol version, client info and capabilities. Two new headers, Mcp-Method and Mcp-Name, copy the JSON-RPC method and (for a tool call) the tool name out of the body and into headers, where proxies already look. Without sessions, an MCP server behaves much like any other HTTP API, which is why the difference between an API and MCP now comes down to who reads the docs. Before the revision, a proxy needed a body-parsing module to learn which tool was being called, and usually session affinity to keep each client on the backend holding its session. Now stock nginx covers the basics:
API Gateway: Build vs Buy and Why Most Teams Choose Wrong
The API gateway decision — whether to build custom routing and middleware infrastructure or to adopt a commercial or open-source gateway product — is one of the more consequential infrastructure choices an API team makes, and it is frequently made at the wrong time with the wrong information.
The wrong time is too early: a team of three engineers building an API with one consumer has different infrastructure requirements than a team of thirty engineers building an API platform with hundreds of consumers. The wrong information is a product comparison done without a realistic understanding of the operational overhead that gateway products introduce regardless of their feature set.
Tag: api monetization
API Monetization Models: How Companies Actually Charge for Access
Stripe charges per transaction. Twilio charges per message and per minute. OpenAI charges per token. Three companies, three completely different units of value, three pricing models built around what actually costs them money or reflects what the customer gets. Picking a monetization model for an API isn’t a marketing decision bolted on at the end — it shapes how the API gets designed in the first place.
Pay-per-call
The simplest model: charge a flat fee for every request, sometimes with volume discounts at higher tiers. Google Maps and most geocoding APIs work this way. It’s easy for a customer to understand and easy for a provider to bill, since usage tracking is just a request counter.
API Monetization Models That Work and the Ones That Drive Developers Away
API monetization is the discipline that sits at the intersection of product design, pricing strategy, and developer experience. Getting it wrong does not just reduce revenue — it drives away the developers whose integrations would have generated long-term value, in favor of short-term extraction that destroys the developer relationship before it matures.
The history of API monetization is populated with cautionary examples: pricing changes that broke the economics of applications built on the API, free tier eliminations that forced migrations at scale, metered pricing structures that made costs unpredictable enough that developers chose self-hosting over consumption. Each of these is a failure of the same kind — pricing that prioritized the API provider’s short-term revenue over the long-term value of developer trust.
Tag: api security
Fuzzing MCP Servers: Generate Bad Arguments From the Tool Schema and Watch What Breaks
You test an MCP server by chatting with it. Ask for the open bugs, get the open bugs, ship it. The model never sends limit: "ten", an empty path or a 200 KB query while you’re watching, so those paths stay dark until a real session hits one. Say it’s the limit. The handler throws, the framework wraps the exception in a 40 KB stack trace, and the model reads all of it, adjusts, and retries with the same bug in a new shape.
Routing LLM Requests by Token Count, Privacy Tag and Cost Ceiling From One Config File
LLM routing usually starts as if statements. One service picks the cheap model for ticket summaries. Another hardcodes the strong model because it needs tool calling. A third has a comment reading “never send this to the cloud” directly above a fallback that sends it to the cloud when the local server times out. Changing a model, a price or a provider means editing all three.
The router worth building is a small one: ordered rules over properties you can compute before the request leaves, written like an nginx config in a single file, with no database and no UI. Input size, whether tools or images are present, a data classification tag, a cost ceiling for the single request, which upstreams are healthy. One binary on a cheap VPS reads the file, accepts the OpenAI request shape and picks where each request goes. The rule that justifies the exercise is that privacy routing fails closed.
Appdome Upgrades MobileBOT Defense With Identity-First Mobile API Protection
Appdome has released six major upgrades to its MobileBOT Defense product, repositioning it as what the company calls the industry’s first full-suite Identity-First Mobile API Protection solution. The update moves the product’s security model away from probabilistic behavioral inference and toward deterministic cryptographic proof — a distinction that has become commercially significant as AI-generated attack tooling has made legacy bot detection increasingly easy to defeat.
The core architectural shift is the introduction of a multi-tiered identity model that governs every API session before access is granted. Prior generations of mobile bot defense relied on web application firewall heuristics and session cookies to infer whether an incoming request was legitimate. That model has a structural weakness: session cookies can be captured and replayed, and applications instrumented with WAF anti-bot SDKs can be repackaged and run inside automated environments. Appdome’s new approach requires that the identity of the application, the device, and the session be cryptographically verified before any API response is issued.
OWASP API Security Top 10: The Vulnerabilities Shipping in Production Right Now
The OWASP API Security Top 10 is updated periodically based on analysis of real API vulnerabilities in production systems. The list is not theoretical. The vulnerabilities it documents are the ones that security researchers find in bug bounty programs, that appear in breach disclosures, and that affect applications built by teams that considered security during development. Their persistence on the list across multiple editions reflects the difficulty of eliminating them in complex systems, not a lack of awareness that they exist.
Rate Limiting Is Not Optional and Most Implementations Are Wrong
Rate limiting is one of the few API design decisions where the failure mode is existential rather than merely inconvenient. An API without rate limiting is an API that can be brought down by a single misbehaving consumer, whether that consumer is a customer with a buggy retry loop, a competitor running a data extraction operation, or an attacker attempting a denial of service. The argument for implementing rate limiting is not about fairness or monetization tiers, though it serves both. It is about operational survival.
API Authentication: JWT, OAuth2, and API Keys Each Have a Job
API authentication is the area where implementation decisions have the most direct security consequences and where the choice of mechanism is most frequently driven by familiarity rather than fit. Teams that have used JWTs extensively reach for JWTs. Teams that have configured OAuth2 once and survived it reach for OAuth2. Teams that want something simple reach for API keys. Each choice reflects a different problem being solved, and using the wrong mechanism for the problem introduces either unnecessary complexity or genuine security gaps.
Tag: api testing
Benchmarking MCP Servers and Stateful API Workflows: Latency, Throughput and Tokens per Call
Point wrk at an MCP server and you get a clean report: every response a 200. Some of those 200s carry isError: true results, and nothing in the output says what the tool definitions cost the model on every turn. The tool is measuring requests per second. An agent runs a workflow, and what the server costs it is latency per call times calls per task, plus the tokens each response and each definition puts into its context.
Fuzzing MCP Servers: Generate Bad Arguments From the Tool Schema and Watch What Breaks
You test an MCP server by chatting with it. Ask for the open bugs, get the open bugs, ship it. The model never sends limit: "ten", an empty path or a 200 KB query while you’re watching, so those paths stay dark until a real session hits one. Say it’s the limit. The handler throws, the framework wraps the exception in a 40 KB stack trace, and the model reads all of it, adjusts, and retries with the same bug in a new shape.
Package a Failed API Request Into One File Anyone Can Replay Locally
A customer’s checkout returns a 500. Support pastes the request ID into the ticket, and the engineer on call finds the log line: KeyError: 'tax_region' in the pricing module. They send the same request locally and get a 200. Of course they do. Their database has no customer with a null tax region, the feature flag that routes to the new tax engine is off in development, the rates service answers differently today, and the clock is a day later. The bug is a function of all of that, and the ticket contains none of it.
Record an Agent's MCP Traffic Once, Then Replay It in CI Without Servers or Credentials
Your agent test passes on your laptop and fails in CI. The laptop has a token for the issue tracker’s MCP server; CI doesn’t, and shouldn’t. Even with a token, the tracker listed three open bugs yesterday and lists four today, so the agent’s summary changes and the assertion on it breaks.
Web developers dealt with this years ago. VCR (Ruby), Polly.js, Betamax and go-vcr record real HTTP responses into a file the first time a test runs, then serve them from that file on every run after. The file is called a cassette. MCP needs the same thing: a proxy that sits between an agent and its MCP servers, writes every exchange into one cassette, and plays it back later with no server, no credentials and no network. mcprec below is an illustrative name for a tool you’d have to build.
Turning Ten Minutes of Production Traffic Into an API Regression Suite
You’re about to refactor the billing endpoints. The service has a few dozen tests, mostly happy paths, and nobody trusts them to catch a changed rounding rule or a renamed field. Writing better ones by hand means reading every handler and inventing inputs. Meanwhile production receives thousands of real inputs a minute, and each one comes labelled with the response your current code gives.
Capturing that traffic is the easy part; a proxy, a packet tap or a log line with the body in it will do. The product is everything after. Ten minutes of traffic holds thousands of near-duplicate requests and a handful that exercise something different, and a tool is only useful if it can tell them apart. Cluster by endpoint, request shape and response shape. Pick representatives that cover the status codes and branches. Assert only on fields that are stable. Mock the downstream calls. What comes out is a few dozen characterization tests (Michael Feathers’ name for tests that pin down what code does today).
API Testing Strategies: What to Test and When
An API can pass every unit test in its suite and still break every client that calls it, because unit tests check that functions do what the code says they do, not that the API does what the contract says it does. That gap is where most production API incidents actually come from: a field renamed, a status code changed from 200 to 204, a required parameter quietly made optional. Testing an API well means testing at several different levels, because each one catches a different class of failure.
API Testing Strategies That Catch the Problems Unit Tests Miss
Unit tests verify that individual functions behave correctly in isolation. They run fast, catch regressions close to where they are introduced, and document expected behavior at the code level. They do not verify that the API endpoints exposed to consumers behave according to the documented contract, that changes in one service do not break the consumers that depend on it, or that the system behaves correctly under the conditions that production traffic creates.
Tag: api tooling
A Tiny ETL Binary Competes With curl, jq and SQLite in a Cron Job, So Build It That Small
The real competitor is a shell script in a crontab, and it usually looks like this:
curl -s "https://api.example.com/v1/launches?limit=100" \
| jq -r '.data[] | [.id, .name, .net] | @csv' \
| sqlite3 -csv launches.db ".import /dev/stdin launches"
It works on the day you write it. Then the API answers 429 and curl pipes an error page into jq. Or the API has a second page, and the script never asks for it. When the job dies halfway, the rerun inserts the same rows again or trips over the primary key, depending on how the table was made. A field that starts arriving as a string goes unnoticed until a chart looks wrong. Retries, backoff, pagination, incremental state, idempotent writes and schema drift: that’s the list, and shell scripts get every item on it wrong in predictable ways. (To be fair, curl --retry covers the first two.)
An AI Agent Flight Recorder Belongs in One Portable File, the Way HAR Did It for HTTP
An agent edits the wrong config file, then spends forty minutes trying to repair its own repair. The user files a bug with a screenshot of the last message. The maintainer asks for logs, and the logs live in four places: the provider’s usage page, the tool server’s stdout, the framework’s debug output, and a terminal scrollback that closed with the window. Nobody can say what the agent saw on turn six.
Benchmarking MCP Servers and Stateful API Workflows: Latency, Throughput and Tokens per Call
Point wrk at an MCP server and you get a clean report: every response a 200. Some of those 200s carry isError: true results, and nothing in the output says what the tool definitions cost the model on every turn. The tool is measuring requests per second. An agent runs a workflow, and what the server costs it is latency per call times calls per task, plus the tokens each response and each definition puts into its context.
Diagnose a Slow API From One Request: DNS, Connect, TLS, Server Wait and Transfer
“The API is slow” starts a hunt. Somebody opens the APM dashboard, somebody else greps the load balancer logs, a third person checks whether the database is on fire. An hour later the team has three theories and no measurement. One request, timed phase by phase, answers the first question in under a second: whether the time went to name lookup, the TCP connect, the TLS handshake, the server or the transfer of the body.
Finding API Endpoints, Tables and Flags Nobody Uses Takes Code and Traffic Together
A team wants to delete GET /v1/invoices/{id}/legacy-pdf. A search across the main repo finds no caller, and the gateway logs show zero hits in the last 30 days. The route goes out in a cleanup PR. On the first business day of the next quarter, a partner’s reconciliation job starts failing: it calls that endpoint four times a year, and nobody on the team knew the partner was still there.
Fuzzing MCP Servers: Generate Bad Arguments From the Tool Schema and Watch What Breaks
You test an MCP server by chatting with it. Ask for the open bugs, get the open bugs, ship it. The model never sends limit: "ten", an empty path or a 200 KB query while you’re watching, so those paths stay dark until a real session hits one. Say it’s the limit. The handler throws, the framework wraps the exception in a 40 KB stack trace, and the model reads all of it, adjusts, and retries with the same bug in a new shape.
Give Any API a History: Poll It, Hash It and Query Old Versions With SQL
Ask a launch schedule API when a rocket flies and you get one date. Ask what the date was last Tuesday, or how many times it has moved, and there’s no endpoint for that. Most APIs describe the present. Prices, timetables, government datasets and status pages all change in place, and the old value is gone the moment the new one is written. That’s a pity, because launch dates slip so often that the list of changes in a launch schedule is more interesting than the current date.
Infer Your API's Real Contract From Traffic, Then Diff It Against the Docs
Your OpenAPI file marks shipping_address as required on GET /orders/{id}. After Tuesday’s deploy, about one response in 300 leaves it out, because a new code path for orders created by the import job skips the field. The docs still say required. The tests still pass, since nobody wrote one for import-job orders. A client with a strict deserializer starts throwing on 0.3% of order pages, and the first report you get is “sometimes the order screen is blank”.
Keeping Third-Party API Responses in SQLite Gets You a Cache, an Offline Mode and a History
The first version of an API cache is a dictionary with a timeout. The second is Redis holding a JSON string under a key built from the URL. The third gets written after an incident, when somebody needs to know what the weather provider returned on Tuesday and the cache has already replaced it with Wednesday’s answer. Every app that depends on an outside API walks the same path: a cache, then a retry layer, then a debugging log, then a wish that it had kept the old responses.
LLM Response Caching Pays Off in CI, Evals and Agent Retries, Not in Chat
A repository has 300 integration tests that each send a prompt to a model. The suite runs on every push to every branch, then again in the merge queue. Most of those runs don’t touch a prompt (the diff was a stylesheet or a migration), so the model receives the same 300 requests it saw an hour earlier, writes roughly the same 300 answers, and the provider bills every one. Nobody chose that. It’s what happens when a test calls a live API.
Make for APIs: Rerun Only the Steps Downstream of an Endpoint That Changed
A nightly job pulls a users endpoint and an orders endpoint, normalizes both, joins them on customer ID and renders a report. On most nights the upstream data hasn’t changed since the last run. The job doesn’t know that, so it downloads and parses everything, reruns every transform and writes the same report again. If the API bills per call, or one step takes twenty minutes, you pay for the same answer every night.
Mapping an Unfamiliar API by Following the IDs Between Its Endpoints
You inherit an integration with a partner API that has 140 endpoints, documented in alphabetical order. GET /accounts sits next to GET /adjustments, and POST /refunds is a long scroll away from the GET /charges/{id} it depends on. Nobody wrote down that a refund hangs off a charge, which hangs off an order, which may or may not have a customer. You find out the slow way: call an endpoint, copy an ID out of the response, paste it into the next call, and keep a diagram in a notebook that’s out of date by Thursday.
MCP Tool Calls Are Plain HTTP Now: Route Them With a Small Proxy Before Buying a Gateway
A platform team runs four MCP servers for its coding agents: GitHub, internal docs search, a read-only Postgres server and the ticketing system. Someone wants per-tool rate limits and a log of which agent called what, so a gateway evaluation goes on the calendar. Nobody has asked the cheaper question yet, which is how much of that the reverse proxy they already run can handle.
Since July, quite a lot. The 2026-07-28 revision made MCP stateless at the protocol layer: the initialize handshake is gone, the Mcp-Session-Id header is gone, and every request carries its own protocol version, client info and capabilities. Two new headers, Mcp-Method and Mcp-Name, copy the JSON-RPC method and (for a tool call) the tool name out of the body and into headers, where proxies already look. Without sessions, an MCP server behaves much like any other HTTP API, which is why the difference between an API and MCP now comes down to who reads the docs. Before the revision, a proxy needed a body-parsing module to learn which tool was being called, and usually session affinity to keep each client on the backend holding its session. Now stock nginx covers the basics:
Most MCP Token Waste Is in Tool Results: Put a Deterministic Reducer Between Server and Model
An agent calls a code-search tool and gets back a hundred hits. Each hit carries dozens of fields: node IDs, a URL for every related resource, avatar links, permission flags. The model needed three of them, a repo, a path and a snippet. The rest now sits in the context window for the remainder of the session, and the model reads past it on every later turn.
Tool definitions get most of the attention in agent token costs, and they’ve earned it. A server that exposes 150 tools puts 150 schemas in front of the model on every turn. Results are the other half of the bill, and they have fewer standard answers. An ordinary API client ignores the fields it doesn’t use, and ignoring is free. A model pays to read every token it’s handed.
Package a Failed API Request Into One File Anyone Can Replay Locally
A customer’s checkout returns a 500. Support pastes the request ID into the ticket, and the engineer on call finds the log line: KeyError: 'tax_region' in the pricing module. They send the same request locally and get a 200. Of course they do. Their database has no customer with a null tax region, the feature flag that routes to the new tax engine is off in development, the rates service answers differently today, and the clock is a day later. The bug is a function of all of that, and the ticket contains none of it.
Record an Agent's MCP Traffic Once, Then Replay It in CI Without Servers or Credentials
Your agent test passes on your laptop and fails in CI. The laptop has a token for the issue tracker’s MCP server; CI doesn’t, and shouldn’t. Even with a token, the tracker listed three open bugs yesterday and lists four today, so the agent’s summary changes and the assertion on it breaks.
Web developers dealt with this years ago. VCR (Ruby), Polly.js, Betamax and go-vcr record real HTTP responses into a file the first time a test runs, then serve them from that file on every run after. The file is called a cassette. MCP needs the same thing: a proxy that sits between an agent and its MCP servers, writes every exchange into one cassette, and plays it back later with no server, no credentials and no network. mcprec below is an illustrative name for a tool you’d have to build.
Routing LLM Requests by Token Count, Privacy Tag and Cost Ceiling From One Config File
LLM routing usually starts as if statements. One service picks the cheap model for ticket summaries. Another hardcodes the strong model because it needs tool calling. A third has a comment reading “never send this to the cloud” directly above a fallback that sends it to the cloud when the local server times out. Changing a model, a price or a provider means editing all three.
The router worth building is a small one: ordered rules over properties you can compute before the request leaves, written like an nginx config in a single file, with no database and no UI. Input size, whether tools or images are present, a data classification tag, a cost ceiling for the single request, which upstreams are healthy. One binary on a cheap VPS reads the file, accepts the OpenAI request shape and picks where each request goes. The rule that justifies the exercise is that privacy routing fails closed.
Stop Reparsing the Same Big JSON Documents: Persist Them as Indexed Binary Instead
A service loads a 40 MB product catalog from disk every time a worker starts. It parses the JSON into objects, builds a map from SKU to product, and answers price lookups until the next deploy. The parse costs seconds of startup. The object tree often costs several times the file’s size in memory, and every worker holds its own copy. A typical request touches two fields of one product. Multiply that by every deploy, every autoscale event and every cold start. Nothing here is broken. The format was built for exchange and it’s being used as a database.
The Best Small Infrastructure Tools Reduce Data Near the Source Instead of Storing More
A gigabyte of disk costs almost nothing. The same gigabyte sent to a log vendor that prices by ingestion costs real money, and pasted into a model’s context window it costs money and answer quality at the same time. Storage is cheap per byte. Everything that touches the bytes afterward is not: ingestion fees, query time, bandwidth on a thin link, a context window that holds only so much, and the attention of whoever has to read the result. Observability is the oldest place this shows up, and agents have just made it louder.
The New MCP Spec Caches Tool Lists but Not Tool Calls, and a Caching Proxy Fills the Gap
An agent works through a ticket and asks a docs-search tool the same question on turn 3, again on turn 14, and again the next morning in a fresh session. Each repeat costs a charge against the upstream’s rate limit and a wait with the model idle, for an answer that never changed. Agents retry after errors and start every session by looking up what the last one already knew.
Trimming 100 KB API Responses to the Five Fields Your Client Uses, at the Proxy
Take a mobile screen that lists orders: a customer name, a status, a total, a date. The endpoint behind it returns 100 KB for one page, because the vendor’s schema carries about sixty fields per order, plus nested addresses, hypermedia links and an audit trail. The phone downloads all of it over whatever connection it has, parses all of it, and keeps five fields. You can’t change the vendor’s API. You can change what reaches the phone.
Turning Ten Minutes of Production Traffic Into an API Regression Suite
You’re about to refactor the billing endpoints. The service has a few dozen tests, mostly happy paths, and nobody trusts them to catch a changed rounding rule or a renamed field. Writing better ones by hand means reading every handler and inventing inputs. Meanwhile production receives thousands of real inputs a minute, and each one comes labelled with the response your current code gives.
Capturing that traffic is the easy part; a proxy, a packet tap or a log line with the body in it will do. The product is everything after. Ten minutes of traffic holds thousands of near-duplicate requests and a handful that exercise something different, and a tool is only useful if it can tell them apart. Cluster by endpoint, request shape and response shape. Pick representatives that cover the status codes and branches. Assert only on fields that are stable. Mock the downstream calls. What comes out is a few dozen characterization tests (Michael Feathers’ name for tests that pin down what code does today).
Five SDK Generators Compared: Speakeasy, Stainless, Fern, APIMatic, and OpenAPI Generator
Speakeasy has published a head-to-head comparison of the five most widely deployed SDK generators for OpenAPI specifications, covering Speakeasy itself alongside Stainless, Fern, APIMatic, and the open-source OpenAPI Generator. The evaluation spans language coverage, runtime type safety, dependency footprint, OpenAPI fidelity, enterprise feature sets, and deployment flexibility — the criteria that now determine whether an SDK generator clears enterprise procurement rather than just developer preference.
SDK generators have moved from convenience tooling to infrastructure. API-first companies, including those building for AI agent integrations, now treat generated client libraries as a production artifact, and the differences between generators surface in SOC 2 audits and supply chain reviews rather than only in developer experience surveys.
Tag: architecture
MCP Tool Calls Are Plain HTTP Now: Route Them With a Small Proxy Before Buying a Gateway
A platform team runs four MCP servers for its coding agents: GitHub, internal docs search, a read-only Postgres server and the ticketing system. Someone wants per-tool rate limits and a log of which agent called what, so a gateway evaluation goes on the calendar. Nobody has asked the cheaper question yet, which is how much of that the reverse proxy they already run can handle.
Since July, quite a lot. The 2026-07-28 revision made MCP stateless at the protocol layer: the initialize handshake is gone, the Mcp-Session-Id header is gone, and every request carries its own protocol version, client info and capabilities. Two new headers, Mcp-Method and Mcp-Name, copy the JSON-RPC method and (for a tool call) the tool name out of the body and into headers, where proxies already look. Without sessions, an MCP server behaves much like any other HTTP API, which is why the difference between an API and MCP now comes down to who reads the docs. Before the revision, a proxy needed a body-parsing module to learn which tool was being called, and usually session affinity to keep each client on the backend holding its session. Now stock nginx covers the basics:
Routing LLM Requests by Token Count, Privacy Tag and Cost Ceiling From One Config File
LLM routing usually starts as if statements. One service picks the cheap model for ticket summaries. Another hardcodes the strong model because it needs tool calling. A third has a comment reading “never send this to the cloud” directly above a fallback that sends it to the cloud when the local server times out. Changing a model, a price or a provider means editing all three.
The router worth building is a small one: ordered rules over properties you can compute before the request leaves, written like an nginx config in a single file, with no database and no UI. Input size, whether tools or images are present, a data classification tag, a cost ceiling for the single request, which upstreams are healthy. One binary on a cheap VPS reads the file, accepts the OpenAI request shape and picks where each request goes. The rule that justifies the exercise is that privacy routing fails closed.
The Best Small Infrastructure Tools Reduce Data Near the Source Instead of Storing More
A gigabyte of disk costs almost nothing. The same gigabyte sent to a log vendor that prices by ingestion costs real money, and pasted into a model’s context window it costs money and answer quality at the same time. Storage is cheap per byte. Everything that touches the bytes afterward is not: ingestion fees, query time, bandwidth on a thin link, a context window that holds only so much, and the attention of whoever has to read the result. Observability is the oldest place this shows up, and agents have just made it louder.
Orkes Raises $60M to Bring Production-Grade AI Orchestration to Enterprise Developers
Orkes, the workflow and agent orchestration platform founded by the original engineers behind Netflix’s microservices infrastructure, has closed a $60 million Series B round led by AVP, with participation from Prosperity7 Ventures, Nexus Venture Partners, Battery Ventures, and Vertex Ventures US. The raise signals growing enterprise demand for orchestration infrastructure that can take AI workloads from prototype to production without falling apart.
The company’s foundation is Conductor, an open-source orchestration engine originated at Netflix in 2016 and still actively maintained by Orkes. Netflix’s own internal usage of Conductor has grown fivefold in recent months, and the project counts developers at JP Morgan Chase, Tesla, Atlassian, Oracle, American Express, and GE Healthcare among its users. Since its $20 million Series A in 2024, Orkes has tripled its paying customer base and built a developer community in the hundreds of thousands.
gRPC in Production: What the Documentation Doesn't Tell You
gRPC documentation is thorough on the protocol’s features and sparse on the operational realities of running it at production scale. The gap between the getting-started experience and the production experience is wide enough to have surprised most of the teams that have made the journey. The surprises are not fatal. They are the kind that would have been useful to know before the architecture decision was made.
The gRPC pitch is compelling: Protocol Buffers serialization that is faster and smaller than JSON, HTTP/2 multiplexing that reduces connection overhead, generated client and server stubs that eliminate serialization bugs, strong typing that catches integration errors at compile time rather than runtime. All of these benefits are real. All of them come with operational requirements that the pitch does not emphasize.
Event-Driven Architecture vs Request-Response: Choosing the Right Communication Pattern
The choice between request-response and event-driven communication patterns is one of the most consequential architectural decisions in distributed system design. It determines how services couple to each other, how failures propagate, how the system scales under load, and how difficult it is to trace the flow of data through the system when things go wrong. Most teams treat it as a technology choice — Kafka versus REST — when it is primarily a design choice about how services should relate to each other.
The Business Case for Internal APIs That Most Engineering Leaders Ignore
Internal APIs — interfaces between services within an organization’s own systems — receive less design attention than public APIs because they lack the external consumer accountability that forces quality. The teams that consume internal APIs are colleagues, not customers. Breaking changes can be coordinated by Slack message rather than deprecation notice. Documentation is optional when the API author sits nearby.
The organizations that operate this way accumulate a specific kind of technical debt: internal integrations that are brittle, undocumented, and implicitly coupled to implementation details that were never meant to be part of the interface. The cost of this debt is the engineering time spent maintaining integrations that should be stable, debugging failures caused by undocumented behavior changes, and slowing down service evolution because teams are afraid to change APIs that other teams depend on in ways nobody has mapped.
The Hidden Costs of Third-Party API Dependencies
Third-party API integrations are the debts that engineering organizations incur with optimism and repay with regret. The integration that takes two days to build and saves six months of custom development looks like an unambiguous win until the third-party API changes its pricing, introduces a breaking change, degrades in availability, or is discontinued entirely. The costs of the dependency were deferred, not eliminated. They appear later, at a time not of the integrating team’s choosing, with a magnitude that was not budgeted.
API Gateway: Build vs Buy and Why Most Teams Choose Wrong
The API gateway decision — whether to build custom routing and middleware infrastructure or to adopt a commercial or open-source gateway product — is one of the more consequential infrastructure choices an API team makes, and it is frequently made at the wrong time with the wrong information.
The wrong time is too early: a team of three engineers building an API with one consumer has different infrastructure requirements than a team of thirty engineers building an API platform with hundreds of consumers. The wrong information is a product comparison done without a realistic understanding of the operational overhead that gateway products introduce regardless of their feature set.
REST vs GraphQL vs gRPC: The Honest Comparison
The choice between REST, GraphQL, and gRPC is treated in most discussions as a question of technical preference when it is primarily a question of context. Each protocol was designed for a specific problem space. Each performs well in that space and poorly outside it. The comparison articles that declare one winner across all use cases are either selling something or have not operated all three at production scale.
REST’s dominance in public API design is not accidental. The constraints it imposes — statelessness, uniform interface, resource-based addressing — map naturally to HTTP’s caching infrastructure, client library ecosystems, and the mental model that most developers already carry from web development. A REST API can be consumed with curl. It can be documented with OpenAPI. It can be cached at the edge. These properties have real operational value that architectural elegance alone cannot purchase.
Tag: authentication
Appdome Upgrades MobileBOT Defense With Identity-First Mobile API Protection
Appdome has released six major upgrades to its MobileBOT Defense product, repositioning it as what the company calls the industry’s first full-suite Identity-First Mobile API Protection solution. The update moves the product’s security model away from probabilistic behavioral inference and toward deterministic cryptographic proof — a distinction that has become commercially significant as AI-generated attack tooling has made legacy bot detection increasingly easy to defeat.
The core architectural shift is the introduction of a multi-tiered identity model that governs every API session before access is granted. Prior generations of mobile bot defense relied on web application firewall heuristics and session cookies to infer whether an incoming request was legitimate. That model has a structural weakness: session cookies can be captured and replayed, and applications instrumented with WAF anti-bot SDKs can be repackaged and run inside automated environments. Appdome’s new approach requires that the identity of the application, the device, and the session be cryptographically verified before any API response is issued.
OWASP API Security Top 10: The Vulnerabilities Shipping in Production Right Now
The OWASP API Security Top 10 is updated periodically based on analysis of real API vulnerabilities in production systems. The list is not theoretical. The vulnerabilities it documents are the ones that security researchers find in bug bounty programs, that appear in breach disclosures, and that affect applications built by teams that considered security during development. Their persistence on the list across multiple editions reflects the difficulty of eliminating them in complex systems, not a lack of awareness that they exist.
API Authentication: JWT, OAuth2, and API Keys Each Have a Job
API authentication is the area where implementation decisions have the most direct security consequences and where the choice of mechanism is most frequently driven by familiarity rather than fit. Teams that have used JWTs extensively reach for JWTs. Teams that have configured OAuth2 once and survived it reach for OAuth2. Teams that want something simple reach for API keys. Each choice reflects a different problem being solved, and using the wrong mechanism for the problem introduces either unnecessary complexity or genuine security gaps.
Tag: caching
Keeping Third-Party API Responses in SQLite Gets You a Cache, an Offline Mode and a History
The first version of an API cache is a dictionary with a timeout. The second is Redis holding a JSON string under a key built from the URL. The third gets written after an incident, when somebody needs to know what the weather provider returned on Tuesday and the cache has already replaced it with Wednesday’s answer. Every app that depends on an outside API walks the same path: a cache, then a retry layer, then a debugging log, then a wish that it had kept the old responses.
LLM Response Caching Pays Off in CI, Evals and Agent Retries, Not in Chat
A repository has 300 integration tests that each send a prompt to a model. The suite runs on every push to every branch, then again in the merge queue. Most of those runs don’t touch a prompt (the diff was a stylesheet or a migration), so the model receives the same 300 requests it saw an hour earlier, writes roughly the same 300 answers, and the provider bills every one. Nobody chose that. It’s what happens when a test calls a live API.
Make for APIs: Rerun Only the Steps Downstream of an Endpoint That Changed
A nightly job pulls a users endpoint and an orders endpoint, normalizes both, joins them on customer ID and renders a report. On most nights the upstream data hasn’t changed since the last run. The job doesn’t know that, so it downloads and parses everything, reruns every transform and writes the same report again. If the API bills per call, or one step takes twenty minutes, you pay for the same answer every night.
The New MCP Spec Caches Tool Lists but Not Tool Calls, and a Caching Proxy Fills the Gap
An agent works through a ticket and asks a docs-search tool the same question on turn 3, again on turn 14, and again the next morning in a fresh session. Each repeat costs a charge against the upstream’s rate limit and a wait with the model idle, for an answer that never changed. Agents retry after errors and start every session by looking up what the last one already knew.
Caching a Third-Party API Response in a Cloudflare Pages Function
Build-time fetching handles most third-party data on a static site. It falls down in one specific case: content that should change on a schedule you are not rebuilding on. A page showing twelve rotating items each day, with a weekly deploy cadence, cannot get its data from the build.
The naive fix puts a fetch in the browser. Every visitor then hits the upstream API directly, which burns through rate limits, exposes any key you are using, and leaves the page empty when the provider has a bad afternoon.
Fetching a Remote JSON API at Build Time in Hugo with resources.GetRemote
Most tutorials that put third-party API data on a static site reach for client-side JavaScript. The page loads, a fetch runs, and content appears a moment later. It works, and it throws away most of what a static site is for. Search engines see an empty container, every visitor costs you an upstream request, and a rate limit or an outage at the provider becomes a broken page for everyone.
Tag: ci/cd
Record an Agent's MCP Traffic Once, Then Replay It in CI Without Servers or Credentials
Your agent test passes on your laptop and fails in CI. The laptop has a token for the issue tracker’s MCP server; CI doesn’t, and shouldn’t. Even with a token, the tracker listed three open bugs yesterday and lists four today, so the agent’s summary changes and the assertion on it breaks.
Web developers dealt with this years ago. VCR (Ruby), Polly.js, Betamax and go-vcr record real HTTP responses into a file the first time a test runs, then serve them from that file on every run after. The file is called a cassette. MCP needs the same thing: a proxy that sits between an agent and its MCP servers, writes every exchange into one cassette, and plays it back later with no server, no credentials and no network. mcprec below is an illustrative name for a tool you’d have to build.
API Testing Strategies: What to Test and When
An API can pass every unit test in its suite and still break every client that calls it, because unit tests check that functions do what the code says they do, not that the API does what the contract says it does. That gap is where most production API incidents actually come from: a field renamed, a status code changed from 200 to 204, a required parameter quietly made optional. Testing an API well means testing at several different levels, because each one catches a different class of failure.
API Testing Strategies That Catch the Problems Unit Tests Miss
Unit tests verify that individual functions behave correctly in isolation. They run fast, catch regressions close to where they are introduced, and document expected behavior at the code level. They do not verify that the API endpoints exposed to consumers behave according to the documented contract, that changes in one service do not break the consumers that depend on it, or that the system behaves correctly under the conditions that production traffic creates.
Tag: cloudflare
Caching a Third-Party API Response in a Cloudflare Pages Function
Build-time fetching handles most third-party data on a static site. It falls down in one specific case: content that should change on a schedule you are not rebuilding on. A page showing twelve rotating items each day, with a weekly deploy cadence, cannot get its data from the build.
The naive fix puts a fetch in the browser. Every visitor then hits the upstream API directly, which burns through rate limits, exposes any key you are using, and leaves the page empty when the provider has a bad afternoon.
Tag: data pipelines
A Tiny ETL Binary Competes With curl, jq and SQLite in a Cron Job, So Build It That Small
The real competitor is a shell script in a crontab, and it usually looks like this:
curl -s "https://api.example.com/v1/launches?limit=100" \
| jq -r '.data[] | [.id, .name, .net] | @csv' \
| sqlite3 -csv launches.db ".import /dev/stdin launches"
It works on the day you write it. Then the API answers 429 and curl pipes an error page into jq. Or the API has a second page, and the script never asks for it. When the job dies halfway, the rerun inserts the same rows again or trips over the primary key, depending on how the table was made. A field that starts arriving as a string goes unnoticed until a chart looks wrong. Retries, backoff, pagination, incremental state, idempotent writes and schema drift: that’s the list, and shell scripts get every item on it wrong in predictable ways. (To be fair, curl --retry covers the first two.)
Make for APIs: Rerun Only the Steps Downstream of an Endpoint That Changed
A nightly job pulls a users endpoint and an orders endpoint, normalizes both, joins them on customer ID and renders a report. On most nights the upstream data hasn’t changed since the last run. The job doesn’t know that, so it downloads and parses everything, reruns every transform and writes the same report again. If the API bills per call, or one step takes twenty minutes, you pay for the same answer every night.
The Best Small Infrastructure Tools Reduce Data Near the Source Instead of Storing More
A gigabyte of disk costs almost nothing. The same gigabyte sent to a log vendor that prices by ingestion costs real money, and pasted into a model’s context window it costs money and answer quality at the same time. Storage is cheap per byte. Everything that touches the bytes afterward is not: ingestion fees, query time, bandwidth on a thin link, a context window that holds only so much, and the attention of whoever has to read the result. Observability is the oldest place this shows up, and agents have just made it louder.
Audit an API Field's Completeness Before You Build a Feature on It
An API’s documentation lists the fields a record can have. It rarely tells you how many records actually have them. Those are different numbers, and on open data APIs the gap is often enormous.
The failure looks like this. You read the schema, spot a field that would make a great feature, build the feature, and then discover the field is populated on four percent of the data. By then the feature is written and the pitch has been made.
Why Private Domain Data Is the Real Key to AI That Actually Works
Every enterprise racing to deploy AI hits the same wall eventually: the outputs are technically impressive but commercially useless. The model knows everything about everything and nothing about your business. That gap — between general capability and contextual intelligence — is a data problem, and it’s the problem KeyAPI.ai is built to solve.
The Generic AI Problem Is a Data Problem
General large language models are trained on public datasets. That makes them broadly knowledgeable and entirely generic. Ask one to help with e-commerce user preference analysis, social media content strategy, or brand marketing targeting, and it will produce polished, plausible, competely undifferentiated output. It has no idea what your customers actually buy, what your community actually says, or what your competitors are actually doing.
Tag: debugging
An AI Agent Flight Recorder Belongs in One Portable File, the Way HAR Did It for HTTP
An agent edits the wrong config file, then spends forty minutes trying to repair its own repair. The user files a bug with a screenshot of the last message. The maintainer asks for logs, and the logs live in four places: the provider’s usage page, the tool server’s stdout, the framework’s debug output, and a terminal scrollback that closed with the window. Nobody can say what the agent saw on turn six.
Diagnose a Slow API From One Request: DNS, Connect, TLS, Server Wait and Transfer
“The API is slow” starts a hunt. Somebody opens the APM dashboard, somebody else greps the load balancer logs, a third person checks whether the database is on fire. An hour later the team has three theories and no measurement. One request, timed phase by phase, answers the first question in under a second: whether the time went to name lookup, the TCP connect, the TLS handshake, the server or the transfer of the body.
Package a Failed API Request Into One File Anyone Can Replay Locally
A customer’s checkout returns a 500. Support pastes the request ID into the ticket, and the engineer on call finds the log line: KeyError: 'tax_region' in the pricing module. They send the same request locally and get a 200. Of course they do. Their database has no customer with a null tax region, the feature flag that routes to the new tax engine is off in development, the rates service answers differently today, and the clock is a day later. The bug is a function of all of that, and the ticket contains none of it.
Tag: developer experience
Every Accident in Your API Becomes a Contract
You don’t get to decide which parts of your API are the API. Your users decide that, and they decide it by accident.
We removed a field once. It was called legacy_status, it duplicated a value that already existed under a better name, and it had been marked deprecated in the docs for a year and a half. Nobody read it. We checked the logs, checked the support tickets, checked with the two biggest accounts, and shipped the removal on a Tuesday.
API Monetization Models That Work and the Ones That Drive Developers Away
API monetization is the discipline that sits at the intersection of product design, pricing strategy, and developer experience. Getting it wrong does not just reduce revenue — it drives away the developers whose integrations would have generated long-term value, in favor of short-term extraction that destroys the developer relationship before it matures.
The history of API monetization is populated with cautionary examples: pricing changes that broke the economics of applications built on the API, free tier eliminations that forced migrations at scale, metered pricing structures that made costs unpredictable enough that developers chose self-hosting over consumption. Each of these is a failure of the same kind — pricing that prioritized the API provider’s short-term revenue over the long-term value of developer trust.
The Business Case for Internal APIs That Most Engineering Leaders Ignore
Internal APIs — interfaces between services within an organization’s own systems — receive less design attention than public APIs because they lack the external consumer accountability that forces quality. The teams that consume internal APIs are colleagues, not customers. Breaking changes can be coordinated by Slack message rather than deprecation notice. Documentation is optional when the API author sits nearby.
The organizations that operate this way accumulate a specific kind of technical debt: internal integrations that are brittle, undocumented, and implicitly coupled to implementation details that were never meant to be part of the interface. The cost of this debt is the engineering time spent maintaining integrations that should be stable, debugging failures caused by undocumented behavior changes, and slowing down service evolution because teams are afraid to change APIs that other teams depend on in ways nobody has mapped.
Breaking Changes: How to Avoid Shipping Them and What to Do When You Must
A breaking change is any modification to an API that requires consumers to update their integration to continue functioning. The definition is straightforward. The practice of avoiding breaking changes while evolving an API requires engineering discipline that most teams underestimate until they have shipped a breaking change to a production API and experienced the resulting incident response.
The instinct to avoid defining something as a breaking change is strong. Removing a field that is not documented is tempting to classify as cleanup rather than a breaking change. Changing an error code from 400 to 422 for a validation failure seems like a trivial semantic correction. Adding a required field to a request body seems like a new feature rather than a breaking change. Each of these reclassifications is wrong, and each produces consumers whose integrations fail after the change.
SDK Design: Making Your API Easy to Use Is Not the Same as Making It Easy to Build
An SDK — a software development kit providing a client library for an API — is the interface through which most developers interact with a third-party API in production. The quality of the SDK determines the quality of the integration experience more than the quality of the underlying API, because most developers never interact with the API directly. They interact with the SDK that wraps it.
The gap between a good API and a good SDK is wide and frequently underestimated. A well-designed API with a poorly designed SDK produces frustrated developers who waste time on integration mechanics instead of building their application. A mediocre API with a well-designed SDK produces developers who build successfully and attribute the quality of their experience to the API provider rather than the SDK.
API Documentation That Developers Actually Use
API documentation is where most APIs fail their consumers silently. The API itself may be well-designed, reliable, and feature-complete. If the documentation is incomplete, inaccurate, or organized without regard for how developers approach integration tasks, the API will generate support tickets, incorrect integrations, and the quiet abandonment of developers who find a better-documented competitor.
The documentation failures that cause the most damage are predictable: reference documentation without examples, error responses that are documented without the conditions that produce them, authentication sections that explain the mechanism but not the specific steps to obtain credentials, and code examples that work when first published and become outdated as the API evolves.
Tag: developer tools
Diagnose a Slow API From One Request: DNS, Connect, TLS, Server Wait and Transfer
“The API is slow” starts a hunt. Somebody opens the APM dashboard, somebody else greps the load balancer logs, a third person checks whether the database is on fire. An hour later the team has three theories and no measurement. One request, timed phase by phase, answers the first question in under a second: whether the time went to name lookup, the TCP connect, the TLS handshake, the server or the transfer of the body.
Finding API Endpoints, Tables and Flags Nobody Uses Takes Code and Traffic Together
A team wants to delete GET /v1/invoices/{id}/legacy-pdf. A search across the main repo finds no caller, and the gateway logs show zero hits in the last 30 days. The route goes out in a cleanup PR. On the first business day of the next quarter, a partner’s reconciliation job starts failing: it calls that endpoint four times a year, and nobody on the team knew the partner was still there.
Mapping an Unfamiliar API by Following the IDs Between Its Endpoints
You inherit an integration with a partner API that has 140 endpoints, documented in alphabetical order. GET /accounts sits next to GET /adjustments, and POST /refunds is a long scroll away from the GET /charges/{id} it depends on. Nobody wrote down that a refund hangs off a charge, which hangs off an order, which may or may not have a customer. You find out the slow way: call an endpoint, copy an ID out of the response, paste it into the next call, and keep a diagram in a notebook that’s out of date by Thursday.
Package a Failed API Request Into One File Anyone Can Replay Locally
A customer’s checkout returns a 500. Support pastes the request ID into the ticket, and the engineer on call finds the log line: KeyError: 'tax_region' in the pricing module. They send the same request locally and get a 200. Of course they do. Their database has no customer with a null tax region, the feature flag that routes to the new tax engine is off in development, the rates service answers differently today, and the clock is a day later. The bug is a function of all of that, and the ticket contains none of it.
Turning Ten Minutes of Production Traffic Into an API Regression Suite
You’re about to refactor the billing endpoints. The service has a few dozen tests, mostly happy paths, and nobody trusts them to catch a changed rounding rule or a renamed field. Writing better ones by hand means reading every handler and inventing inputs. Meanwhile production receives thousands of real inputs a minute, and each one comes labelled with the response your current code gives.
Capturing that traffic is the easy part; a proxy, a packet tap or a log line with the body in it will do. The product is everything after. Ten minutes of traffic holds thousands of near-duplicate requests and a handful that exercise something different, and a tool is only useful if it can tell them apart. Cluster by endpoint, request shape and response shape. Pick representatives that cover the status codes and branches. Assert only on fields that are stable. Mock the downstream calls. What comes out is a few dozen characterization tests (Michael Feathers’ name for tests that pin down what code does today).
API Monetization Models: How Companies Actually Charge for Access
Stripe charges per transaction. Twilio charges per message and per minute. OpenAI charges per token. Three companies, three completely different units of value, three pricing models built around what actually costs them money or reflects what the customer gets. Picking a monetization model for an API isn’t a marketing decision bolted on at the end — it shapes how the API gets designed in the first place.
Pay-per-call
The simplest model: charge a flat fee for every request, sometimes with volume discounts at higher tiers. Google Maps and most geocoding APIs work this way. It’s easy for a customer to understand and easy for a provider to bill, since usage tracking is just a request counter.
API Testing Strategies: What to Test and When
An API can pass every unit test in its suite and still break every client that calls it, because unit tests check that functions do what the code says they do, not that the API does what the contract says it does. That gap is where most production API incidents actually come from: a field renamed, a status code changed from 200 to 204, a required parameter quietly made optional. Testing an API well means testing at several different levels, because each one catches a different class of failure.
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Orkes Raises $60M to Bring Production-Grade AI Orchestration to Enterprise Developers
Orkes, the workflow and agent orchestration platform founded by the original engineers behind Netflix’s microservices infrastructure, has closed a $60 million Series B round led by AVP, with participation from Prosperity7 Ventures, Nexus Venture Partners, Battery Ventures, and Vertex Ventures US. The raise signals growing enterprise demand for orchestration infrastructure that can take AI workloads from prototype to production without falling apart.
The company’s foundation is Conductor, an open-source orchestration engine originated at Netflix in 2016 and still actively maintained by Orkes. Netflix’s own internal usage of Conductor has grown fivefold in recent months, and the project counts developers at JP Morgan Chase, Tesla, Atlassian, Oracle, American Express, and GE Healthcare among its users. Since its $20 million Series A in 2024, Orkes has tripled its paying customer base and built a developer community in the hundreds of thousands.
Tag: documentation
API Documentation That Developers Actually Use
API documentation is where most APIs fail their consumers silently. The API itself may be well-designed, reliable, and feature-complete. If the documentation is incomplete, inaccurate, or organized without regard for how developers approach integration tasks, the API will generate support tickets, incorrect integrations, and the quiet abandonment of developers who find a better-documented competitor.
The documentation failures that cause the most damage are predictable: reference documentation without examples, error responses that are documented without the conditions that produce them, authentication sections that explain the mechanism but not the specific steps to obtain credentials, and code examples that work when first published and become outdated as the API evolves.
Tag: event-driven
Event-Driven Architecture vs Request-Response: Choosing the Right Communication Pattern
The choice between request-response and event-driven communication patterns is one of the most consequential architectural decisions in distributed system design. It determines how services couple to each other, how failures propagate, how the system scales under load, and how difficult it is to trace the flow of data through the system when things go wrong. Most teams treat it as a technology choice — Kafka versus REST — when it is primarily a design choice about how services should relate to each other.
Webhooks vs Polling: The Decision Most Teams Get Backwards
The polling versus webhooks decision is frequently made on the basis of what the API provider finds easiest to implement rather than what serves consumers best. Polling is easier to provide — it requires no additional infrastructure beyond the existing API endpoints. Webhooks require the provider to maintain delivery infrastructure, handle failures, implement retry logic, and manage consumer endpoint registration. The provider’s preference for polling is understandable. For the consumers who pay the operational cost of polling, it is not a neutral choice.
Tag: graphql
The GraphQL N+1 Problem and How to Actually Fix It
The N+1 query problem is the GraphQL performance issue that every team encounters and few solve completely before it causes a production incident. Its mechanics are straightforward. Its solutions are well-documented. Its persistence in production systems reflects the gap between understanding a problem and implementing a solution that holds under all the query patterns a flexible API allows.
A GraphQL query that requests a list of posts and the author of each post produces, in a naive resolver implementation, one database query to fetch the posts and one database query per post to fetch each author. A query requesting 100 posts with their authors produces 101 database queries. A query requesting 1,000 posts produces 1,001. The number of database queries grows linearly with the number of items in the list — hence N+1, where N is the list length and 1 is the initial list query.
REST vs GraphQL vs gRPC: The Honest Comparison
The choice between REST, GraphQL, and gRPC is treated in most discussions as a question of technical preference when it is primarily a question of context. Each protocol was designed for a specific problem space. Each performs well in that space and poorly outside it. The comparison articles that declare one winner across all use cases are either selling something or have not operated all three at production scale.
REST’s dominance in public API design is not accidental. The constraints it imposes — statelessness, uniform interface, resource-based addressing — map naturally to HTTP’s caching infrastructure, client library ecosystems, and the mental model that most developers already carry from web development. A REST API can be consumed with curl. It can be documented with OpenAPI. It can be cached at the edge. These properties have real operational value that architectural elegance alone cannot purchase.
Tag: grpc
gRPC in Production: What the Documentation Doesn't Tell You
gRPC documentation is thorough on the protocol’s features and sparse on the operational realities of running it at production scale. The gap between the getting-started experience and the production experience is wide enough to have surprised most of the teams that have made the journey. The surprises are not fatal. They are the kind that would have been useful to know before the architecture decision was made.
The gRPC pitch is compelling: Protocol Buffers serialization that is faster and smaller than JSON, HTTP/2 multiplexing that reduces connection overhead, generated client and server stubs that eliminate serialization bugs, strong typing that catches integration errors at compile time rather than runtime. All of these benefits are real. All of them come with operational requirements that the pitch does not emphasize.
REST vs GraphQL vs gRPC: The Honest Comparison
The choice between REST, GraphQL, and gRPC is treated in most discussions as a question of technical preference when it is primarily a question of context. Each protocol was designed for a specific problem space. Each performs well in that space and poorly outside it. The comparison articles that declare one winner across all use cases are either selling something or have not operated all three at production scale.
REST’s dominance in public API design is not accidental. The constraints it imposes — statelessness, uniform interface, resource-based addressing — map naturally to HTTP’s caching infrastructure, client library ecosystems, and the mental model that most developers already carry from web development. A REST API can be consumed with curl. It can be documented with OpenAPI. It can be cached at the edge. These properties have real operational value that architectural elegance alone cannot purchase.
Tag: http
Idempotency Keys: How One Header Stops a Retry From Charging a Customer Twice
A client sends a POST to create a payment. The server charges the card, writes the record, and starts sending the response. Then the connection drops. The client sees a timeout and has no way to tell whether the charge happened. If it retries, the customer may pay twice. If it doesn’t, the order may never complete.
Every API that creates or changes something over a network has this problem. GET, PUT and DELETE are idempotent by definition in HTTP, so repeating them is safe. POST and PATCH aren’t. The fix most payment APIs settled on is a client-generated key sent with the request, which the server uses to recognize a retry and hand back the original answer instead of doing the work again.
Diagnose a Slow API From One Request: DNS, Connect, TLS, Server Wait and Transfer
“The API is slow” starts a hunt. Somebody opens the APM dashboard, somebody else greps the load balancer logs, a third person checks whether the database is on fire. An hour later the team has three theories and no measurement. One request, timed phase by phase, answers the first question in under a second: whether the time went to name lookup, the TCP connect, the TLS handshake, the server or the transfer of the body.
HTTP Status Codes Are Being Used Wrong and It Is Your Problem Too
The HTTP status code specification is 30 years old, fully documented, and widely misimplemented. The misimplementation is not ignorance — most API developers know that 200 means success and 404 means not found. It is the edge cases where the correct status code requires a moment of thought that the wrong choice gets made, and the wrong choice gets propagated to every consumer who must now handle an error that does not mean what the specification says it means.
Tag: hugo
Fetching a Remote JSON API at Build Time in Hugo with resources.GetRemote
Most tutorials that put third-party API data on a static site reach for client-side JavaScript. The page loads, a fetch runs, and content appears a moment later. It works, and it throws away most of what a static site is for. Search engines see an empty container, every visitor costs you an upstream request, and a rate limit or an outage at the provider becomes a broken page for everyone.
Tag: json
A Tiny ETL Binary Competes With curl, jq and SQLite in a Cron Job, So Build It That Small
The real competitor is a shell script in a crontab, and it usually looks like this:
curl -s "https://api.example.com/v1/launches?limit=100" \
| jq -r '.data[] | [.id, .name, .net] | @csv' \
| sqlite3 -csv launches.db ".import /dev/stdin launches"
It works on the day you write it. Then the API answers 429 and curl pipes an error page into jq. Or the API has a second page, and the script never asks for it. When the job dies halfway, the rerun inserts the same rows again or trips over the primary key, depending on how the table was made. A field that starts arriving as a string goes unnoticed until a chart looks wrong. Retries, backoff, pagination, incremental state, idempotent writes and schema drift: that’s the list, and shell scripts get every item on it wrong in predictable ways. (To be fair, curl --retry covers the first two.)
Give Any API a History: Poll It, Hash It and Query Old Versions With SQL
Ask a launch schedule API when a rocket flies and you get one date. Ask what the date was last Tuesday, or how many times it has moved, and there’s no endpoint for that. Most APIs describe the present. Prices, timetables, government datasets and status pages all change in place, and the old value is gone the moment the new one is written. That’s a pity, because launch dates slip so often that the list of changes in a launch schedule is more interesting than the current date.
Infer Your API's Real Contract From Traffic, Then Diff It Against the Docs
Your OpenAPI file marks shipping_address as required on GET /orders/{id}. After Tuesday’s deploy, about one response in 300 leaves it out, because a new code path for orders created by the import job skips the field. The docs still say required. The tests still pass, since nobody wrote one for import-job orders. A client with a strict deserializer starts throwing on 0.3% of order pages, and the first report you get is “sometimes the order screen is blank”.
Keeping Third-Party API Responses in SQLite Gets You a Cache, an Offline Mode and a History
The first version of an API cache is a dictionary with a timeout. The second is Redis holding a JSON string under a key built from the URL. The third gets written after an incident, when somebody needs to know what the weather provider returned on Tuesday and the cache has already replaced it with Wednesday’s answer. Every app that depends on an outside API walks the same path: a cache, then a retry layer, then a debugging log, then a wish that it had kept the old responses.
Most MCP Token Waste Is in Tool Results: Put a Deterministic Reducer Between Server and Model
An agent calls a code-search tool and gets back a hundred hits. Each hit carries dozens of fields: node IDs, a URL for every related resource, avatar links, permission flags. The model needed three of them, a repo, a path and a snippet. The rest now sits in the context window for the remainder of the session, and the model reads past it on every later turn.
Tool definitions get most of the attention in agent token costs, and they’ve earned it. A server that exposes 150 tools puts 150 schemas in front of the model on every turn. Results are the other half of the bill, and they have fewer standard answers. An ordinary API client ignores the fields it doesn’t use, and ignoring is free. A model pays to read every token it’s handed.
Stop Reparsing the Same Big JSON Documents: Persist Them as Indexed Binary Instead
A service loads a 40 MB product catalog from disk every time a worker starts. It parses the JSON into objects, builds a map from SKU to product, and answers price lookups until the next deploy. The parse costs seconds of startup. The object tree often costs several times the file’s size in memory, and every worker holds its own copy. A typical request touches two fields of one product. Multiply that by every deploy, every autoscale event and every cold start. Nothing here is broken. The format was built for exchange and it’s being used as a database.
Trimming 100 KB API Responses to the Five Fields Your Client Uses, at the Proxy
Take a mobile screen that lists orders: a customer name, a status, a total, a date. The endpoint behind it returns 100 KB for one page, because the vendor’s schema carries about sixty fields per order, plus nested addresses, hypermedia links and an audit trail. The phone downloads all of it over whatever connection it has, parses all of it, and keeps five fields. You can’t change the vendor’s API. You can change what reaches the phone.
Audit an API Field's Completeness Before You Build a Feature on It
An API’s documentation lists the fields a record can have. It rarely tells you how many records actually have them. Those are different numbers, and on open data APIs the gap is often enormous.
The failure looks like this. You read the schema, spot a field that would make a great feature, build the feature, and then discover the field is populated on four percent of the data. By then the feature is written and the pitch has been made.
Fetching a Remote JSON API at Build Time in Hugo with resources.GetRemote
Most tutorials that put third-party API data on a static site reach for client-side JavaScript. The page loads, a fetch runs, and content appears a moment later. It works, and it throws away most of what a static site is for. Search engines see an empty container, every visitor costs you an upstream request, and a rate limit or an outage at the provider becomes a broken page for everyone.
Querying USAspending for Federal Contract Awards With a POST Search and No API Key
USAspending publishes every federal award the United States government makes, and the API needs no key, no registration and no authorization header. That combination is rare enough on government data that it is worth saying twice.
The thing that stops most people is the shape of the request. The interesting endpoints are POST, the body is a nested object, and a wrong field name gets you a 400 with little explanation. Here is the working version.
Reading the Launch Library API for Rocket Launch Schedules Without a Key
The Space Devs run Launch Library, a REST API covering orbital and suborbital launches worldwide, past and upcoming. No key, no signup, and a forward schedule that currently runs to 369 launches. If you need a dated calendar of something genuinely interesting, this is one of the easiest open APIs to consume.
The Endpoints
Base URL carries the version in the path:
https://ll.thespacedevs.com/2.3.0/
The three that matter:
launches/upcoming/ everything scheduled ahead
launches/previous/ everything flown
launches/ both
events/upcoming/ spacewalks, dockings, test fires
A minimal call:
Tag: licensing
GBIF's API Returns CC BY-NC Images by Default, Which Breaks Commercial Use
GBIF is one of the better open data APIs. No key, no registration, generous limits, and well over a billion species occurrence records, a large share of them carrying photographs. It is an obvious source if you need images of living things and you do not want to pay a stock library.
There is a trap in the default response, and it is the kind that does not surface until someone sends you a letter.
Tag: llm apis
An AI Agent Flight Recorder Belongs in One Portable File, the Way HAR Did It for HTTP
An agent edits the wrong config file, then spends forty minutes trying to repair its own repair. The user files a bug with a screenshot of the last message. The maintainer asks for logs, and the logs live in four places: the provider’s usage page, the tool server’s stdout, the framework’s debug output, and a terminal scrollback that closed with the window. Nobody can say what the agent saw on turn six.
LLM Response Caching Pays Off in CI, Evals and Agent Retries, Not in Chat
A repository has 300 integration tests that each send a prompt to a model. The suite runs on every push to every branch, then again in the merge queue. Most of those runs don’t touch a prompt (the diff was a stylesheet or a migration), so the model receives the same 300 requests it saw an hour earlier, writes roughly the same 300 answers, and the provider bills every one. Nobody chose that. It’s what happens when a test calls a live API.
Most MCP Token Waste Is in Tool Results: Put a Deterministic Reducer Between Server and Model
An agent calls a code-search tool and gets back a hundred hits. Each hit carries dozens of fields: node IDs, a URL for every related resource, avatar links, permission flags. The model needed three of them, a repo, a path and a snippet. The rest now sits in the context window for the remainder of the session, and the model reads past it on every later turn.
Tool definitions get most of the attention in agent token costs, and they’ve earned it. A server that exposes 150 tools puts 150 schemas in front of the model on every turn. Results are the other half of the bill, and they have fewer standard answers. An ordinary API client ignores the fields it doesn’t use, and ignoring is free. A model pays to read every token it’s handed.
Routing LLM Requests by Token Count, Privacy Tag and Cost Ceiling From One Config File
LLM routing usually starts as if statements. One service picks the cheap model for ticket summaries. Another hardcodes the strong model because it needs tool calling. A third has a comment reading “never send this to the cloud” directly above a fallback that sends it to the cloud when the local server times out. Changing a model, a price or a provider means editing all three.
The router worth building is a small one: ordered rules over properties you can compute before the request leaves, written like an nginx config in a single file, with no database and no UI. Input size, whether tools or images are present, a data classification tag, a cost ceiling for the single request, which upstreams are healthy. One binary on a cheap VPS reads the file, accepts the OpenAI request shape and picks where each request goes. The rule that justifies the exercise is that privacy routing fails closed.
The New MCP Spec Caches Tool Lists but Not Tool Calls, and a Caching Proxy Fills the Gap
An agent works through a ticket and asks a docs-search tool the same question on turn 3, again on turn 14, and again the next morning in a fresh session. Each repeat costs a charge against the upstream’s rate limit and a wait with the model idle, for an answer that never changed. Agents retry after errors and start every session by looking up what the last one already knew.
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Why Private Domain Data Is the Real Key to AI That Actually Works
Every enterprise racing to deploy AI hits the same wall eventually: the outputs are technically impressive but commercially useless. The model knows everything about everything and nothing about your business. That gap — between general capability and contextual intelligence — is a data problem, and it’s the problem KeyAPI.ai is built to solve.
The Generic AI Problem Is a Data Problem
General large language models are trained on public datasets. That makes them broadly knowledgeable and entirely generic. Ask one to help with e-commerce user preference analysis, social media content strategy, or brand marketing targeting, and it will produce polished, plausible, competely undifferentiated output. It has no idea what your customers actually buy, what your community actually says, or what your competitors are actually doing.
Tag: mcp
Benchmarking MCP Servers and Stateful API Workflows: Latency, Throughput and Tokens per Call
Point wrk at an MCP server and you get a clean report: every response a 200. Some of those 200s carry isError: true results, and nothing in the output says what the tool definitions cost the model on every turn. The tool is measuring requests per second. An agent runs a workflow, and what the server costs it is latency per call times calls per task, plus the tokens each response and each definition puts into its context.
Fuzzing MCP Servers: Generate Bad Arguments From the Tool Schema and Watch What Breaks
You test an MCP server by chatting with it. Ask for the open bugs, get the open bugs, ship it. The model never sends limit: "ten", an empty path or a 200 KB query while you’re watching, so those paths stay dark until a real session hits one. Say it’s the limit. The handler throws, the framework wraps the exception in a 40 KB stack trace, and the model reads all of it, adjusts, and retries with the same bug in a new shape.
MCP Tool Calls Are Plain HTTP Now: Route Them With a Small Proxy Before Buying a Gateway
A platform team runs four MCP servers for its coding agents: GitHub, internal docs search, a read-only Postgres server and the ticketing system. Someone wants per-tool rate limits and a log of which agent called what, so a gateway evaluation goes on the calendar. Nobody has asked the cheaper question yet, which is how much of that the reverse proxy they already run can handle.
Since July, quite a lot. The 2026-07-28 revision made MCP stateless at the protocol layer: the initialize handshake is gone, the Mcp-Session-Id header is gone, and every request carries its own protocol version, client info and capabilities. Two new headers, Mcp-Method and Mcp-Name, copy the JSON-RPC method and (for a tool call) the tool name out of the body and into headers, where proxies already look. Without sessions, an MCP server behaves much like any other HTTP API, which is why the difference between an API and MCP now comes down to who reads the docs. Before the revision, a proxy needed a body-parsing module to learn which tool was being called, and usually session affinity to keep each client on the backend holding its session. Now stock nginx covers the basics:
Most MCP Token Waste Is in Tool Results: Put a Deterministic Reducer Between Server and Model
An agent calls a code-search tool and gets back a hundred hits. Each hit carries dozens of fields: node IDs, a URL for every related resource, avatar links, permission flags. The model needed three of them, a repo, a path and a snippet. The rest now sits in the context window for the remainder of the session, and the model reads past it on every later turn.
Tool definitions get most of the attention in agent token costs, and they’ve earned it. A server that exposes 150 tools puts 150 schemas in front of the model on every turn. Results are the other half of the bill, and they have fewer standard answers. An ordinary API client ignores the fields it doesn’t use, and ignoring is free. A model pays to read every token it’s handed.
Record an Agent's MCP Traffic Once, Then Replay It in CI Without Servers or Credentials
Your agent test passes on your laptop and fails in CI. The laptop has a token for the issue tracker’s MCP server; CI doesn’t, and shouldn’t. Even with a token, the tracker listed three open bugs yesterday and lists four today, so the agent’s summary changes and the assertion on it breaks.
Web developers dealt with this years ago. VCR (Ruby), Polly.js, Betamax and go-vcr record real HTTP responses into a file the first time a test runs, then serve them from that file on every run after. The file is called a cassette. MCP needs the same thing: a proxy that sits between an agent and its MCP servers, writes every exchange into one cassette, and plays it back later with no server, no credentials and no network. mcprec below is an illustrative name for a tool you’d have to build.
The Best Small Infrastructure Tools Reduce Data Near the Source Instead of Storing More
A gigabyte of disk costs almost nothing. The same gigabyte sent to a log vendor that prices by ingestion costs real money, and pasted into a model’s context window it costs money and answer quality at the same time. Storage is cheap per byte. Everything that touches the bytes afterward is not: ingestion fees, query time, bandwidth on a thin link, a context window that holds only so much, and the attention of whoever has to read the result. Observability is the oldest place this shows up, and agents have just made it louder.
The New MCP Spec Caches Tool Lists but Not Tool Calls, and a Caching Proxy Fills the Gap
An agent works through a ticket and asks a docs-search tool the same question on turn 3, again on turn 14, and again the next morning in a fresh session. Each repeat costs a charge against the upstream’s rate limit and a wait with the model idle, for an answer that never changed. Agents retry after errors and start every session by looking up what the last one already knew.
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Why Private Domain Data Is the Real Key to AI That Actually Works
Every enterprise racing to deploy AI hits the same wall eventually: the outputs are technically impressive but commercially useless. The model knows everything about everything and nothing about your business. That gap — between general capability and contextual intelligence — is a data problem, and it’s the problem KeyAPI.ai is built to solve.
The Generic AI Problem Is a Data Problem
General large language models are trained on public datasets. That makes them broadly knowledgeable and entirely generic. Ask one to help with e-commerce user preference analysis, social media content strategy, or brand marketing targeting, and it will produce polished, plausible, competely undifferentiated output. It has no idea what your customers actually buy, what your community actually says, or what your competitors are actually doing.
Form.io Launches MCP Server and Agentic Coding Toolset for Governed Enterprise AI Development
Form.io has released an MCP Server, Skills library, and Agentic Coding Plugin designed to bring schema-governed infrastructure to AI coding environments — extending its existing Universal Agent Gateway into the build-time layer. The toolset targets enterprise development teams using agentic coding tools such as Claude Code, Cursor, and Windsurf, where the default outcome is speed without standardization.
The problem Form.io is addressing is real and increasingly visible. As agentic coding accelerates across large organizations, applications generated by independent teams diverge in architecture, data handling, and compliance posture. Each agent makes its own decisions; five teams produce five incompatible implementations of the same solution. The efficiency gains nominally promised by agentic coding are offset by the governance overhead required to manage the fragmentation afterward.
Tag: mobile
Trimming 100 KB API Responses to the Five Fields Your Client Uses, at the Proxy
Take a mobile screen that lists orders: a customer name, a status, a total, a date. The endpoint behind it returns 100 KB for one page, because the vendor’s schema carries about sixty fields per order, plus nested addresses, hypermedia links and an audit trail. The phone downloads all of it over whatever connection it has, parses all of it, and keeps five fields. You can’t change the vendor’s API. You can change what reaches the phone.
Appdome Upgrades MobileBOT Defense With Identity-First Mobile API Protection
Appdome has released six major upgrades to its MobileBOT Defense product, repositioning it as what the company calls the industry’s first full-suite Identity-First Mobile API Protection solution. The update moves the product’s security model away from probabilistic behavioral inference and toward deterministic cryptographic proof — a distinction that has become commercially significant as AI-generated attack tooling has made legacy bot detection increasingly easy to defeat.
The core architectural shift is the introduction of a multi-tiered identity model that governs every API session before access is granted. Prior generations of mobile bot defense relied on web application firewall heuristics and session cookies to infer whether an incoming request was legitimate. That model has a structural weakness: session cookies can be captured and replayed, and applications instrumented with WAF anti-bot SDKs can be repackaged and run inside automated environments. Appdome’s new approach requires that the identity of the application, the device, and the session be cryptographically verified before any API response is issued.
Tag: observability
An AI Agent Flight Recorder Belongs in One Portable File, the Way HAR Did It for HTTP
An agent edits the wrong config file, then spends forty minutes trying to repair its own repair. The user files a bug with a screenshot of the last message. The maintainer asks for logs, and the logs live in four places: the provider’s usage page, the tool server’s stdout, the framework’s debug output, and a terminal scrollback that closed with the window. Nobody can say what the agent saw on turn six.
The Best Small Infrastructure Tools Reduce Data Near the Source Instead of Storing More
A gigabyte of disk costs almost nothing. The same gigabyte sent to a log vendor that prices by ingestion costs real money, and pasted into a model’s context window it costs money and answer quality at the same time. Storage is cheap per byte. Everything that touches the bytes afterward is not: ingestion fees, query time, bandwidth on a thin link, a context window that holds only so much, and the attention of whoever has to read the result. Observability is the oldest place this shows up, and agents have just made it louder.
Tag: openapi
Mapping an Unfamiliar API by Following the IDs Between Its Endpoints
You inherit an integration with a partner API that has 140 endpoints, documented in alphabetical order. GET /accounts sits next to GET /adjustments, and POST /refunds is a long scroll away from the GET /charges/{id} it depends on. Nobody wrote down that a refund hangs off a charge, which hangs off an order, which may or may not have a customer. You find out the slow way: call an endpoint, copy an ID out of the response, paste it into the next call, and keep a diagram in a notebook that’s out of date by Thursday.
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Five SDK Generators Compared: Speakeasy, Stainless, Fern, APIMatic, and OpenAPI Generator
Speakeasy has published a head-to-head comparison of the five most widely deployed SDK generators for OpenAPI specifications, covering Speakeasy itself alongside Stainless, Fern, APIMatic, and the open-source OpenAPI Generator. The evaluation spans language coverage, runtime type safety, dependency footprint, OpenAPI fidelity, enterprise feature sets, and deployment flexibility — the criteria that now determine whether an SDK generator clears enterprise procurement rather than just developer preference.
SDK generators have moved from convenience tooling to infrastructure. API-first companies, including those building for AI agent integrations, now treat generated client libraries as a production artifact, and the differences between generators surface in SOC 2 audits and supply chain reviews rather than only in developer experience surveys.
OpenAPI Has Won. Here Is What That Actually Means for Your API.
The API specification format wars ended without a formal declaration of victory. RAML, API Blueprint, WSDL, and a half-dozen proprietary formats all had moments of advocacy and adoption. OpenAPI — originally released as Swagger by Wordnik, donated to the Linux Foundation, and renamed — outlasted them through a combination of tooling ecosystem depth, industry adoption breadth, and the practical network effects that come from being the format that most developers encounter first.
API Documentation That Developers Actually Use
API documentation is where most APIs fail their consumers silently. The API itself may be well-designed, reliable, and feature-complete. If the documentation is incomplete, inaccurate, or organized without regard for how developers approach integration tasks, the API will generate support tickets, incorrect integrations, and the quiet abandonment of developers who find a better-documented competitor.
The documentation failures that cause the most damage are predictable: reference documentation without examples, error responses that are documented without the conditions that produce them, authentication sections that explain the mechanism but not the specific steps to obtain credentials, and code examples that work when first published and become outdated as the API evolves.
Tag: pagination
A Tiny ETL Binary Competes With curl, jq and SQLite in a Cron Job, So Build It That Small
The real competitor is a shell script in a crontab, and it usually looks like this:
curl -s "https://api.example.com/v1/launches?limit=100" \
| jq -r '.data[] | [.id, .name, .net] | @csv' \
| sqlite3 -csv launches.db ".import /dev/stdin launches"
It works on the day you write it. Then the API answers 429 and curl pipes an error page into jq. Or the API has a second page, and the script never asks for it. When the job dies halfway, the rerun inserts the same rows again or trips over the primary key, depending on how the table was made. A field that starts arriving as a string goes unnoticed until a chart looks wrong. Retries, backoff, pagination, incremental state, idempotent writes and schema drift: that’s the list, and shell scripts get every item on it wrong in predictable ways. (To be fair, curl --retry covers the first two.)
Querying USAspending for Federal Contract Awards With a POST Search and No API Key
USAspending publishes every federal award the United States government makes, and the API needs no key, no registration and no authorization header. That combination is rare enough on government data that it is worth saying twice.
The thing that stops most people is the shape of the request. The interesting endpoints are POST, the body is a nested object, and a wrong field name gets you a 400 with little explanation. Here is the working version.
Reading the Launch Library API for Rocket Launch Schedules Without a Key
The Space Devs run Launch Library, a REST API covering orbital and suborbital launches worldwide, past and upcoming. No key, no signup, and a forward schedule that currently runs to 369 launches. If you need a dated calendar of something genuinely interesting, this is one of the easiest open APIs to consume.
The Endpoints
Base URL carries the version in the path:
https://ll.thespacedevs.com/2.3.0/
The three that matter:
launches/upcoming/ everything scheduled ahead
launches/previous/ everything flown
launches/ both
events/upcoming/ spacewalks, dockings, test fires
A minimal call:
Pagination Strategies for Large Datasets and Why Offset Pagination Fails
Offset pagination — the pattern where a consumer requests a page by specifying how many records to skip — is the default choice for most APIs because it maps naturally to SQL’s LIMIT and OFFSET clauses and allows consumers to request any page directly by number. It is also the pagination strategy that fails most visibly at scale and produces the most confusing behavior when underlying data changes between page requests.
Tag: performance
Benchmarking MCP Servers and Stateful API Workflows: Latency, Throughput and Tokens per Call
Point wrk at an MCP server and you get a clean report: every response a 200. Some of those 200s carry isError: true results, and nothing in the output says what the tool definitions cost the model on every turn. The tool is measuring requests per second. An agent runs a workflow, and what the server costs it is latency per call times calls per task, plus the tokens each response and each definition puts into its context.
Diagnose a Slow API From One Request: DNS, Connect, TLS, Server Wait and Transfer
“The API is slow” starts a hunt. Somebody opens the APM dashboard, somebody else greps the load balancer logs, a third person checks whether the database is on fire. An hour later the team has three theories and no measurement. One request, timed phase by phase, answers the first question in under a second: whether the time went to name lookup, the TCP connect, the TLS handshake, the server or the transfer of the body.
Stop Reparsing the Same Big JSON Documents: Persist Them as Indexed Binary Instead
A service loads a 40 MB product catalog from disk every time a worker starts. It parses the JSON into objects, builds a map from SKU to product, and answers price lookups until the next deploy. The parse costs seconds of startup. The object tree often costs several times the file’s size in memory, and every worker holds its own copy. A typical request touches two fields of one product. Multiply that by every deploy, every autoscale event and every cold start. Nothing here is broken. The format was built for exchange and it’s being used as a database.
Trimming 100 KB API Responses to the Five Fields Your Client Uses, at the Proxy
Take a mobile screen that lists orders: a customer name, a status, a total, a date. The endpoint behind it returns 100 KB for one page, because the vendor’s schema carries about sixty fields per order, plus nested addresses, hypermedia links and an audit trail. The phone downloads all of it over whatever connection it has, parses all of it, and keeps five fields. You can’t change the vendor’s API. You can change what reaches the phone.
gRPC in Production: What the Documentation Doesn't Tell You
gRPC documentation is thorough on the protocol’s features and sparse on the operational realities of running it at production scale. The gap between the getting-started experience and the production experience is wide enough to have surprised most of the teams that have made the journey. The surprises are not fatal. They are the kind that would have been useful to know before the architecture decision was made.
The gRPC pitch is compelling: Protocol Buffers serialization that is faster and smaller than JSON, HTTP/2 multiplexing that reduces connection overhead, generated client and server stubs that eliminate serialization bugs, strong typing that catches integration errors at compile time rather than runtime. All of these benefits are real. All of them come with operational requirements that the pitch does not emphasize.
The GraphQL N+1 Problem and How to Actually Fix It
The N+1 query problem is the GraphQL performance issue that every team encounters and few solve completely before it causes a production incident. Its mechanics are straightforward. Its solutions are well-documented. Its persistence in production systems reflects the gap between understanding a problem and implementing a solution that holds under all the query patterns a flexible API allows.
A GraphQL query that requests a list of posts and the author of each post produces, in a naive resolver implementation, one database query to fetch the posts and one database query per post to fetch each author. A query requesting 100 posts with their authors produces 101 database queries. A query requesting 1,000 posts produces 1,001. The number of database queries grows linearly with the number of items in the list — hence N+1, where N is the list length and 1 is the initial list query.
Pagination Strategies for Large Datasets and Why Offset Pagination Fails
Offset pagination — the pattern where a consumer requests a page by specifying how many records to skip — is the default choice for most APIs because it maps naturally to SQL’s LIMIT and OFFSET clauses and allows consumers to request any page directly by number. It is also the pagination strategy that fails most visibly at scale and produces the most confusing behavior when underlying data changes between page requests.
Tag: public apis
Give Any API a History: Poll It, Hash It and Query Old Versions With SQL
Ask a launch schedule API when a rocket flies and you get one date. Ask what the date was last Tuesday, or how many times it has moved, and there’s no endpoint for that. Most APIs describe the present. Prices, timetables, government datasets and status pages all change in place, and the old value is gone the moment the new one is written. That’s a pity, because launch dates slip so often that the list of changes in a launch schedule is more interesting than the current date.
Audit an API Field's Completeness Before You Build a Feature on It
An API’s documentation lists the fields a record can have. It rarely tells you how many records actually have them. Those are different numbers, and on open data APIs the gap is often enormous.
The failure looks like this. You read the schema, spot a field that would make a great feature, build the feature, and then discover the field is populated on four percent of the data. By then the feature is written and the pitch has been made.
GBIF's API Returns CC BY-NC Images by Default, Which Breaks Commercial Use
GBIF is one of the better open data APIs. No key, no registration, generous limits, and well over a billion species occurrence records, a large share of them carrying photographs. It is an obvious source if you need images of living things and you do not want to pay a stock library.
There is a trap in the default response, and it is the kind that does not surface until someone sends you a letter.
Querying USAspending for Federal Contract Awards With a POST Search and No API Key
USAspending publishes every federal award the United States government makes, and the API needs no key, no registration and no authorization header. That combination is rare enough on government data that it is worth saying twice.
The thing that stops most people is the shape of the request. The interesting endpoints are POST, the body is a nested object, and a wrong field name gets you a 400 with little explanation. Here is the working version.
Reading the Launch Library API for Rocket Launch Schedules Without a Key
The Space Devs run Launch Library, a REST API covering orbital and suborbital launches worldwide, past and upcoming. No key, no signup, and a forward schedule that currently runs to 369 launches. If you need a dated calendar of something genuinely interesting, this is one of the easiest open APIs to consume.
The Endpoints
Base URL carries the version in the path:
https://ll.thespacedevs.com/2.3.0/
The three that matter:
launches/upcoming/ everything scheduled ahead
launches/previous/ everything flown
launches/ both
events/upcoming/ spacewalks, dockings, test fires
A minimal call:
Tag: rate limiting
Rate Limiting Is Not Optional and Most Implementations Are Wrong
Rate limiting is one of the few API design decisions where the failure mode is existential rather than merely inconvenient. An API without rate limiting is an API that can be brought down by a single misbehaving consumer, whether that consumer is a customer with a buggy retry loop, a competitor running a data extraction operation, or an attacker attempting a denial of service. The argument for implementing rate limiting is not about fairness or monetization tiers, though it serves both. It is about operational survival.
Tag: rest
Querying USAspending for Federal Contract Awards With a POST Search and No API Key
USAspending publishes every federal award the United States government makes, and the API needs no key, no registration and no authorization header. That combination is rare enough on government data that it is worth saying twice.
The thing that stops most people is the shape of the request. The interesting endpoints are POST, the body is a nested object, and a wrong field name gets you a 400 with little explanation. Here is the working version.
Reading the Launch Library API for Rocket Launch Schedules Without a Key
The Space Devs run Launch Library, a REST API covering orbital and suborbital launches worldwide, past and upcoming. No key, no signup, and a forward schedule that currently runs to 369 launches. If you need a dated calendar of something genuinely interesting, this is one of the easiest open APIs to consume.
The Endpoints
Base URL carries the version in the path:
https://ll.thespacedevs.com/2.3.0/
The three that matter:
launches/upcoming/ everything scheduled ahead
launches/previous/ everything flown
launches/ both
events/upcoming/ spacewalks, dockings, test fires
A minimal call:
Every Accident in Your API Becomes a Contract
You don’t get to decide which parts of your API are the API. Your users decide that, and they decide it by accident.
We removed a field once. It was called legacy_status, it duplicated a value that already existed under a better name, and it had been marked deprecated in the docs for a year and a half. Nobody read it. We checked the logs, checked the support tickets, checked with the two biggest accounts, and shipped the removal on a Tuesday.
HTTP Status Codes Are Being Used Wrong and It Is Your Problem Too
The HTTP status code specification is 30 years old, fully documented, and widely misimplemented. The misimplementation is not ignorance — most API developers know that 200 means success and 404 means not found. It is the edge cases where the correct status code requires a moment of thought that the wrong choice gets made, and the wrong choice gets propagated to every consumer who must now handle an error that does not mean what the specification says it means.
REST vs GraphQL vs gRPC: The Honest Comparison
The choice between REST, GraphQL, and gRPC is treated in most discussions as a question of technical preference when it is primarily a question of context. Each protocol was designed for a specific problem space. Each performs well in that space and poorly outside it. The comparison articles that declare one winner across all use cases are either selling something or have not operated all three at production scale.
REST’s dominance in public API design is not accidental. The constraints it imposes — statelessness, uniform interface, resource-based addressing — map naturally to HTTP’s caching infrastructure, client library ecosystems, and the mental model that most developers already carry from web development. A REST API can be consumed with curl. It can be documented with OpenAPI. It can be cached at the edge. These properties have real operational value that architectural elegance alone cannot purchase.
Tag: sdks
AI Platforms for Designing APIs in 2026: Spec Editors, SDK Generators, MCP Builders and AI Gateways Reviewed
Ask two developers in 2026 what platform they use to design an API, and you will get two answers that have almost nothing in common. One of them means the tool where they write the OpenAPI document, lint it, mock it and publish the reference docs. The other means the layer that sits between their application and a dozen model providers, routing requests to whichever LLM is cheapest or still up. Both groups call it “API design.” Both groups are right, because the two stacks have quietly grown into each other.
Five SDK Generators Compared: Speakeasy, Stainless, Fern, APIMatic, and OpenAPI Generator
Speakeasy has published a head-to-head comparison of the five most widely deployed SDK generators for OpenAPI specifications, covering Speakeasy itself alongside Stainless, Fern, APIMatic, and the open-source OpenAPI Generator. The evaluation spans language coverage, runtime type safety, dependency footprint, OpenAPI fidelity, enterprise feature sets, and deployment flexibility — the criteria that now determine whether an SDK generator clears enterprise procurement rather than just developer preference.
SDK generators have moved from convenience tooling to infrastructure. API-first companies, including those building for AI agent integrations, now treat generated client libraries as a production artifact, and the differences between generators surface in SOC 2 audits and supply chain reviews rather than only in developer experience surveys.
SDK Design: Making Your API Easy to Use Is Not the Same as Making It Easy to Build
An SDK — a software development kit providing a client library for an API — is the interface through which most developers interact with a third-party API in production. The quality of the SDK determines the quality of the integration experience more than the quality of the underlying API, because most developers never interact with the API directly. They interact with the SDK that wraps it.
The gap between a good API and a good SDK is wide and frequently underestimated. A well-designed API with a poorly designed SDK produces frustrated developers who waste time on integration mechanics instead of building their application. A mediocre API with a well-designed SDK produces developers who build successfully and attribute the quality of their experience to the API provider rather than the SDK.
OpenAPI Has Won. Here Is What That Actually Means for Your API.
The API specification format wars ended without a formal declaration of victory. RAML, API Blueprint, WSDL, and a half-dozen proprietary formats all had moments of advocacy and adoption. OpenAPI — originally released as Swagger by Wordnik, donated to the Linux Foundation, and renamed — outlasted them through a combination of tooling ecosystem depth, industry adoption breadth, and the practical network effects that come from being the format that most developers encounter first.
Tag: sqlite
Idempotency Keys: How One Header Stops a Retry From Charging a Customer Twice
A client sends a POST to create a payment. The server charges the card, writes the record, and starts sending the response. Then the connection drops. The client sees a timeout and has no way to tell whether the charge happened. If it retries, the customer may pay twice. If it doesn’t, the order may never complete.
Every API that creates or changes something over a network has this problem. GET, PUT and DELETE are idempotent by definition in HTTP, so repeating them is safe. POST and PATCH aren’t. The fix most payment APIs settled on is a client-generated key sent with the request, which the server uses to recognize a retry and hand back the original answer instead of doing the work again.
A Tiny ETL Binary Competes With curl, jq and SQLite in a Cron Job, So Build It That Small
The real competitor is a shell script in a crontab, and it usually looks like this:
curl -s "https://api.example.com/v1/launches?limit=100" \
| jq -r '.data[] | [.id, .name, .net] | @csv' \
| sqlite3 -csv launches.db ".import /dev/stdin launches"
It works on the day you write it. Then the API answers 429 and curl pipes an error page into jq. Or the API has a second page, and the script never asks for it. When the job dies halfway, the rerun inserts the same rows again or trips over the primary key, depending on how the table was made. A field that starts arriving as a string goes unnoticed until a chart looks wrong. Retries, backoff, pagination, incremental state, idempotent writes and schema drift: that’s the list, and shell scripts get every item on it wrong in predictable ways. (To be fair, curl --retry covers the first two.)
Keeping Third-Party API Responses in SQLite Gets You a Cache, an Offline Mode and a History
The first version of an API cache is a dictionary with a timeout. The second is Redis holding a JSON string under a key built from the URL. The third gets written after an incident, when somebody needs to know what the weather provider returned on Tuesday and the cache has already replaced it with Wednesday’s answer. Every app that depends on an outside API walks the same path: a cache, then a retry layer, then a debugging log, then a wish that it had kept the old responses.
Stop Reparsing the Same Big JSON Documents: Persist Them as Indexed Binary Instead
A service loads a 40 MB product catalog from disk every time a worker starts. It parses the JSON into objects, builds a map from SKU to product, and answers price lookups until the next deploy. The parse costs seconds of startup. The object tree often costs several times the file’s size in memory, and every worker holds its own copy. A typical request touches two fields of one product. Multiply that by every deploy, every autoscale event and every cold start. Nothing here is broken. The format was built for exchange and it’s being used as a database.
Tag: static sites
Caching a Third-Party API Response in a Cloudflare Pages Function
Build-time fetching handles most third-party data on a static site. It falls down in one specific case: content that should change on a schedule you are not rebuilding on. A page showing twelve rotating items each day, with a weekly deploy cadence, cannot get its data from the build.
The naive fix puts a fetch in the browser. Every visitor then hits the upstream API directly, which burns through rate limits, exposes any key you are using, and leaves the page empty when the provider has a bad afternoon.
Fetching a Remote JSON API at Build Time in Hugo with resources.GetRemote
Most tutorials that put third-party API data on a static site reach for client-side JavaScript. The page loads, a fetch runs, and content appears a moment later. It works, and it throws away most of what a static site is for. Search engines see an empty container, every visitor costs you an upstream request, and a rate limit or an outage at the provider becomes a broken page for everyone.
Tag: third-party apis
Keeping Third-Party API Responses in SQLite Gets You a Cache, an Offline Mode and a History
The first version of an API cache is a dictionary with a timeout. The second is Redis holding a JSON string under a key built from the URL. The third gets written after an incident, when somebody needs to know what the weather provider returned on Tuesday and the cache has already replaced it with Wednesday’s answer. Every app that depends on an outside API walks the same path: a cache, then a retry layer, then a debugging log, then a wish that it had kept the old responses.
The Hidden Costs of Third-Party API Dependencies
Third-party API integrations are the debts that engineering organizations incur with optimism and repay with regret. The integration that takes two days to build and saves six months of custom development looks like an unambiguous win until the third-party API changes its pricing, introduces a breaking change, degrades in availability, or is discontinued entirely. The costs of the dependency were deferred, not eliminated. They appear later, at a time not of the integrating team’s choosing, with a magnitude that was not budgeted.
Tag: versioning
Finding API Endpoints, Tables and Flags Nobody Uses Takes Code and Traffic Together
A team wants to delete GET /v1/invoices/{id}/legacy-pdf. A search across the main repo finds no caller, and the gateway logs show zero hits in the last 30 days. The route goes out in a cleanup PR. On the first business day of the next quarter, a partner’s reconciliation job starts failing: it calls that endpoint four times a year, and nobody on the team knew the partner was still there.
Infer Your API's Real Contract From Traffic, Then Diff It Against the Docs
Your OpenAPI file marks shipping_address as required on GET /orders/{id}. After Tuesday’s deploy, about one response in 300 leaves it out, because a new code path for orders created by the import job skips the field. The docs still say required. The tests still pass, since nobody wrote one for import-job orders. A client with a strict deserializer starts throwing on 0.3% of order pages, and the first report you get is “sometimes the order screen is blank”.
Every Accident in Your API Becomes a Contract
You don’t get to decide which parts of your API are the API. Your users decide that, and they decide it by accident.
We removed a field once. It was called legacy_status, it duplicated a value that already existed under a better name, and it had been marked deprecated in the docs for a year and a half. Nobody read it. We checked the logs, checked the support tickets, checked with the two biggest accounts, and shipped the removal on a Tuesday.
Breaking Changes: How to Avoid Shipping Them and What to Do When You Must
A breaking change is any modification to an API that requires consumers to update their integration to continue functioning. The definition is straightforward. The practice of avoiding breaking changes while evolving an API requires engineering discipline that most teams underestimate until they have shipped a breaking change to a production API and experienced the resulting incident response.
The instinct to avoid defining something as a breaking change is strong. Removing a field that is not documented is tempting to classify as cleanup rather than a breaking change. Changing an error code from 400 to 422 for a validation failure seems like a trivial semantic correction. Adding a required field to a request body seems like a new feature rather than a breaking change. Each of these reclassifications is wrong, and each produces consumers whose integrations fail after the change.
API Versioning Strategies That Don't Break Your Consumers
API versioning is the discipline that separates API providers who have operated public APIs for several years from those who have not. Early-stage API design focuses on what the API should do. Mature API design focuses on how the API will evolve without breaking the consumers who have built on top of it. The difference in focus reflects a difference in experience with the consequences of getting it wrong.
Breaking changes are changes that require consumers to modify their integration to continue functioning. They include removing endpoints, removing fields from responses, changing field names, changing data types, changing authentication requirements, and changing the semantics of existing parameters. Every team that has shipped a breaking change to a public API without a migration path has received the same feedback from affected consumers, expressed with varying degrees of professionalism.
Tag: webhooks
Give Any API a History: Poll It, Hash It and Query Old Versions With SQL
Ask a launch schedule API when a rocket flies and you get one date. Ask what the date was last Tuesday, or how many times it has moved, and there’s no endpoint for that. Most APIs describe the present. Prices, timetables, government datasets and status pages all change in place, and the old value is gone the moment the new one is written. That’s a pity, because launch dates slip so often that the list of changes in a launch schedule is more interesting than the current date.
Webhooks vs Polling: The Decision Most Teams Get Backwards
The polling versus webhooks decision is frequently made on the basis of what the API provider finds easiest to implement rather than what serves consumers best. Polling is easier to provide — it requires no additional infrastructure beyond the existing API endpoints. Webhooks require the provider to maintain delivery infrastructure, handle failures, implement retry logic, and manage consumer endpoint registration. The provider’s preference for polling is understandable. For the consumers who pay the operational cost of polling, it is not a neutral choice.