DEV Community

Rom C
Rom C

Posted on

Your API Call Just Crossed a Border. Did You Notice?

A teammate opened a PR last month that looked completely unremarkable: swap the in-house keyword search for a semantic search endpoint, three files changed, tests passing. It got approved in about ten minutes. Nobody flagged it, because there was nothing to flag in the diff itself.
What the diff didn't show was that the new semantic search call routed every query — including whatever a user had typed, which sometimes included their own name, email, or account details — through a third-party embeddings API hosted in a region the team had never discussed. Nothing about that showed up in the code review, the test suite, or the deploy checklist. It only surfaced three weeks later, when a customer's security team asked exactly which regions their data touched.
That's the part of shipping AI features that doesn't fit neatly into a pull request: the data residency implications of a single API call are invisible to every tool we normally use to catch problems.

Why this slips past code review

Code review is built to catch logic errors, style violations, missing tests, and security issues like injection or auth bypass. It's not built to answer "which country does this request leave through, and what happens to the payload once it gets there." That question doesn't map to any linter rule or CI check most teams have running.
Add an SDK, call .complete() or .embed(), get a response back — the request looks identical whether it's hitting an endpoint in the same region as your primary database or one on another continent. The interface is the same. The residency implications are completely different, and the code gives you no visual signal either way.
That snippet passes every test you'd normally write. It also might be the single line in your entire codebase most likely to trigger a failed security review.

The stack has more border crossings than anyone maps

  • A typical AI feature built in the last two years touches more regions than most engineers would guess if asked cold:
  • The application server, wherever it's deployed
  • A vector database or cache, often on a different provider or region than the primary DB
  • The embeddings or completion API, which may run through infrastructure the model provider controls, not you
  • Logging and observability tooling that captures request/response payloads for debugging
  • Any evaluation or fine-tuning pipeline that samples production traffic to improve the model
  • Each of those is a separate hop, added by a separate engineer, at a separate time, usually without anyone asking "where does this data physically go" as part of the decision.

It's not negligence — it's that the question isn't part of the default checklist anywhere in the stack. This is exactly the gap covered in Questa AI's piece on
AI Data Residency: How Businesses Control Data Location— it's aimed at a broader business audience, but the underlying problem it describes is one engineers create, one API integration at a time, without ever seeing it as a single connected system.

Residency, sovereignty, and the layer most stacks skip

Two concepts get conflated constantly, and the difference matters technically, not just legally. Data residency is where bytes are stored at rest. Data sovereignty is whose legal jurisdiction governs those bytes, independent of where they sit. A request can be fully GDPR-compliant on storage and still cross a jurisdictional line the moment it hits an inference endpoint outside the approved region — even if the response is never persisted anywhere.
For engineers, the practical version of this is: storage location tells you where the data rests. Request routing tells you where it's actually been. Most architecture diagrams only document the first one.

A lightweight way to actually see this

You don't need a compliance framework to start closing this gap — you need visibility into your own outbound calls. A few practical steps that don't require a new team or a procurement cycle:

  • Grep the codebase for every SDK client instantiation that calls an external AI/ML API, and note the documented region for each one.
  • Check whether your logging pipeline captures full request/response payloads, and if so, where those logs are stored and for how long.
  • For any vector store or cache, confirm its region matches — or is at least documented separately from — your primary database's region.
  • Add a one-line comment or annotation at each external AI call site noting the data region, so the next engineer touching that code doesn't have to reverse-engineer it.
  • None of this requires new infrastructure. It requires treating "where does this call go" as a normal part of adding any external API dependency — the same instinct that already makes engineers check rate limits and auth scopes before shipping an integration.

Why this becomes your problem, not just legal's

When a customer's security team asks where data is processed, the answer usually has to come from engineering, because legal doesn't know which SDK calls exist in the codebase and legal definitely doesn't know which region a given API key is scoped to. If the answer isn't already documented, someone gets pulled off a sprint to go find it under deadline pressure — and that's the actual cost most teams underestimate. It's not a compliance fine. It's an engineer spending two days reconstructing a data flow map that could have been a comment in the code the day it was written.
I wrote about the buyer-facing version of this in a piece on why your AI vendor might not know where your data lives, and the internal, unsanctioned-tool version of it in a piece on shadow AI usage inside companies. This post is the third leg of the same problem: the one that gets introduced in a completely ordinary-looking pull request.

What good looks like at the code level

Teams that handle this well aren't necessarily using different vendors — they're documenting the same integrations differently. A short, current data-flow doc listing every external AI call, its region, and its retention policy, updated as part of the PR template whenever a new external API is added, turns a two-day fire drill into a five-minute lookup. It's the technical equivalent of keeping a dependency manifest current — nobody loves maintaining it, and everybody's grateful it exists the one time it actually matters.
There's a longer walkthrough of what that documentation actually needs to cover in Where Does Your AI Actually Keep Your Data?, if you want the fuller checklist rather than the engineering-specific version here.

The takeaway

Data residency isn't a legal add-on to an AI feature — it's a property of the request path, decided the moment someone picks an SDK and a region, usually without discussion. Code review will catch a SQL injection risk in that same PR without blinking. It won't catch a jurisdiction problem, because nothing in the tooling is looking for one.
If your team ships AI features regularly, it's worth a single afternoon mapping every external AI call in the codebase to its actual region. It's a lot cheaper to do that on a normal Tuesday than during a customer's security review.

Top comments (0)