Skip to main content
    All articles

    API Key Authentication for Court Data: Best Practices

    12 June 202614 min readCourtMesh Team
    Cover card headed The Leak Is Not the Case Records, with the line: it is the query log

    Ask a developer what a leaked court data API key costs and the answer is usually reassuring. The data is public. Judgments are published. Somebody would get some case records they could have looked up themselves on a government portal. Annoying, a bit of billing exposure, not a crisis.

    That answer is wrong, and it is wrong in a way specific to legal work. The exposure is not the case records. It is the query log. Every authenticated call is logged against the key that made it, which means anyone holding your key, and anyone who obtains the log, can see which parties your firm searched, which statutory provisions you pulled, which High Courts you filtered to, and, most tellingly, when you started looking.

    Consider what that reveals. A sequence of searches against a named company, followed by queries about section 34 of the Arbitration and Conciliation Act 1996, followed by a sweep of NCLT filings involving that company's subsidiaries, is not a data leak. It is your case theory, six weeks before you file. A research trail is work product, and in the hands of the counterparty it is worth considerably more than the judgments it retrieved.

    That is the argument of this piece: legal data credentials deserve the hygiene you already apply to payment credentials, and for a reason payments do not have, which is that the queries themselves are privileged strategy. What follows is how to actually do it, grounded in how the CourtMesh API issues and tracks keys, with the endpoint reference.

    What a Leaked Key Actually Exposes

    Set out the exposure properly, because the mitigation only makes sense once the threat is stated accurately.

    Your research trail

    Which parties, which sections, which courts, which years, in what order and on what dates. This is the shape of a case being built. A counterparty who sees you sweeping section 138 Negotiable Instruments Act 1881 complaints against their directors knows exactly what is coming and has time to prepare.

    Your client list, by inference

    Nobody researches a company at length for fun. A pattern of queries about an entity, sustained over weeks, strongly implies a retainer. That inference is available to anyone reading the log even though no client name was ever sent.

    Timing, which is the sharpest signal

    The date your queries started tells a counterparty when instructions were taken. Against a limitation question under the Limitation Act 1963, or the window for a challenge, the date you began looking is itself a fact somebody can use.

    Your credit balance and capacity

    A stolen key spends your AI credits. Semantic search and analysis endpoints consume credits, and analyze-consolidated consumes materially more than a single case analysis. An attacker with no interest in your data at all can still exhaust your allowance and take your product down.

    Notice that only the last of these is a conventional API security problem. The first three are confidentiality problems, and they are governed by obligations that predate every API you have ever integrated. An advocate's duty of confidence to a client extends to the fact of the retainer and to the work done under it. A research trail is work done under it.

    The judgments are public. The fact that your firm was reading them, in that order, starting on that date, is not.

    How the Credential Actually Works

    Good hygiene follows from understanding the mechanism, so here is the mechanism precisely.

    A key is presented on every authenticated request in one of two headers: X-API-Key carrying the key, or Authorization carrying Bearer followed by the key. Either is accepted, so choose whichever your HTTP client handles most reliably and be consistent. Keys have a defined shape: a prefix, then 32 base64url characters, then a four character suffix, in the form cm-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-XXXX. Legacy keys issued with a vv- prefix continue to work. GET /health is the only endpoint that requires no key at all.

    The property that should shape everything you do next: keys are stored server side only as bcrypt hashes. The plaintext is displayed once, at creation, and cannot be recovered afterwards by you, by support, or by anyone with database access. There is no lookup that returns your key.

    This is the correct design and it is worth understanding why. A hashed credential store means that a breach of the provider's database does not hand an attacker working keys. It also means that any provider whose support team can read your key back to you is storing it reversibly, and their database is a single point of catastrophic failure for every customer at once. When you evaluate a legal data vendor, ask whether support can recover a lost key. The right answer is no, and a vendor who offers the convenience is telling you something important about their storage.

    Shown once means captured once

    Because the plaintext is unrecoverable, the moment of creation is the only moment you can capture it correctly. Put it straight into your secret manager. Not into a terminal you will scroll back through, not into a note you will tidy up later, not into a message to a colleague. The five seconds between generation and storage is the entire window in which the credential can be mishandled, and in practice that window is where most leaks originate.

    The Rules, and Why Each One Exists

    Never ship a key in client code

    This is the one that still causes most incidents, and the reasoning is often subtly wrong rather than absent. Developers know not to commit a key to a public repository. Fewer internalise that any key present in a browser bundle, a mobile application binary, or a desktop application is already public, whatever the repository's visibility. Minification is not obfuscation. A single view-source, or a few minutes with a decompiler, retrieves it.

    The correct architecture is unambiguous: the key lives on your server, your client talks to your server, and your server talks to the court data API. That backend proxy is not overhead. It is where you enforce your own authorisation, apply your own rate shaping ahead of the 10 requests per minute limit on API key traffic, cache case records so you are not spending budget refetching a judgment that has not changed since 1994, and log which of your users searched what.

    That last point deserves emphasis. Without a proxy you have one key making all calls, and your provider's per key log shows one blended stream. With a proxy you know which of your users ran which query, which is exactly the record you need when a partner asks who searched a particular counterparty.

    One key per environment and per workload

    The single shared key is convenient for about a month. Then it becomes the thing that makes every incident maximally expensive, because revoking it takes down production, staging, the nightly ingestion job and the partner integration simultaneously.

    Split by environment first: development, staging and production never share a credential. Then split by workload, which is the part teams skip. Your interactive user facing path and your overnight backfill should hold different keys even in the same environment. Two reasons. Revocation becomes narrow: a leaked backfill key is revoked without a lawyer losing their search box. And attribution becomes possible: because every call is logged per key, separate keys mean you can see immediately which workload consumed the rate budget or burned the AI credits, instead of inferring it from timestamps.

    KeyUsed byWhy it is separate
    Production interactiveThe backend proxy serving live user searchesThe one credential that must never be revoked in a hurry. Isolating it means every other incident can be resolved by revocation without user impact.
    Production batchOvernight ingestion, backfills, scheduled refreshes of pending matter statusHigh volume, unattended, and the most likely to sit in a CI configuration. Revoking it delays a job rather than breaking a product.
    StagingPre production testing against real responsesHeld by more people and deployed more casually than production. Treat it as semi public and never let it reach production data paths.
    Local developmentIndividual developer machinesThe highest leak probability of any key you hold, because it lives in dotfiles, shells and screen shares. Per developer keys mean one careless moment revokes one person.
    Per integration partnerAny third party or separate internal product calling on your behalfEnding a relationship should be a revocation, not a coordinated rotation across every system you run.

    Rotate on a schedule, and rotate without downtime

    Rotation is unpopular because most teams have only ever done it in an emergency, where it is stressful and error prone. Done routinely it is dull, and dullness is the objective: a rotation you have performed four times without incident is a rotation you can perform confidently at nine at night when a key has leaked.

    1

    Issue the new key and store it immediately

    The plaintext appears once. It goes directly into your secret manager under a versioned name. Never into a chat message, a ticket, a spreadsheet, or an email, because every one of those systems retains it somewhere you do not control and will not remember to clean.

    2

    Deploy the new key alongside the old one

    Your configuration should support reading a primary and a secondary credential. Deploy with the new key as primary while the old remains valid. Nothing has been broken yet and nothing has been switched off, which is what makes the step safe to perform during business hours.

    3

    Verify the new key is carrying real traffic

    Watch lastUsedAt on the new key and the per key transaction log for successful calls at the volume you expect. This is the step that catches the deployment that quietly rolled back, or the one service still reading configuration from somewhere you forgot about.

    4

    Confirm the old key has gone quiet

    Watch lastUsedAt on the old key until it stops advancing. If it is still moving, something is still using it, and you want to know what before you deactivate it rather than after. This is precisely the visibility that per key logging exists to give you.

    5

    Deactivate the old key

    A deactivated key returns 401 with the message that the API key is deactivated, which is deliberately distinct from an invalid key. If something you missed is still calling, that specific error tells you what happened in one line rather than sending you hunting through a generic authentication failure.

    6

    Write down the date and set the next one

    Rotation that depends on somebody remembering does not happen. Put it on a schedule with the same seriousness as a limitation date, because an unrotated credential accumulates exposure every month it survives.

    Monitor per key, and know what normal looks like

    Every authenticated call is logged against the key that made it: endpoint, method, status code, response time, sanitised headers, query parameters and body, IP address and user agent, with lastUsedAt updated on every call. Sensitive header and body values, including authorization, cookie, x-api-key, password, token and secret, are redacted before storage, so a key that your own client accidentally echoes into a request body does not end up sitting in a log.

    That log is a detection capability, and it is wasted unless somebody has decided what normal looks like. Establish a baseline for each key: which endpoints it touches, roughly what volume, from which IP ranges, at which hours. Then alert on deviation.

    • A key calling an endpoint it has never called. Your batch ingestion key suddenly hitting the semantic search endpoint is either an undocumented feature launch or somebody else holding your credential.
    • Traffic from an unexpected IP or user agent. A production key whose calls have always come from two static addresses now arriving from a residential connection is worth an immediate look.
    • Volume outside the pattern. Sustained calls at the ceiling of 10 requests per minute from a key that normally runs at a fraction of that, particularly outside working hours.
    • A rise in 401 responses. Repeated authentication failures against your account can be an attacker probing formats, or your own rotation half completed. Both need attention and the log distinguishes them.
    • 403 responses on AI endpoints. Credit exhaustion is a billing state, not a credential failure, and it deserves its own alert. An unexplained one means somebody is spending your allowance.
    • lastUsedAt on a key you believed was dormant. The single cheapest check available. A retired key that is still being used has not been retired.

    Never log the key on your own side

    The provider redacts sensitive values before storage. Your own systems, by default, do not. Request debugging middleware that dumps outbound headers, an exception tracker capturing local variables, a verbose HTTP client in a container log, a support bundle collected from a developer machine: every one of these routinely captures credentials in plaintext and ships them somewhere with weaker access control than your secret manager. Add explicit redaction to your own logging before you turn on verbose HTTP debugging, not after an incident review tells you to.

    The Legal Layer: DPDP 2023 and Professional Confidence

    Credential hygiene here is not only an engineering preference. Two distinct sets of obligations sit on top of it, and they point the same way.

    The first is statutory. Under the Digital Personal Data Protection Act 2023, an entity determining the purpose and means of processing personal data is a data fiduciary, with duties including implementing reasonable security safeguards to prevent personal data breach, and obligations of notification when a breach occurs. Court records are full of personal data: parties, addresses, and in many matter types information that is sensitive by any ordinary reading. When you retrieve that data through an API and store it in your own systems, you are processing it, and the key controlling that retrieval is one of your safeguards. A credential shipped in a mobile binary is not a reasonable security safeguard, and it will not be easy to characterise as one after the fact.

    The second is professional and older. Confidentiality between advocate and client is not limited to the contents of a communication. It extends to the existence of the retainer and to the work carried out under it. Legal research is that work. A query log showing sustained research into a named counterparty, particular provisions and particular forums is a record of privileged strategy, held in a system whose access control is a single string.

    Which is the whole argument compressed: a payment credential, if leaked, exposes money, and money is recoverable. A legal research credential, if leaked, exposes strategy, and strategy is not recoverable once the other side has seen it. The case for treating court data keys with payment grade hygiene is not that the data is equally sensitive. It is that the disclosure is less reversible.

    How Keys Actually Leak

    Almost none of these are sophisticated. They are the same handful, repeating, and each is preventable by a decision taken before the code is written.

    A key committed in an early prototype, removed in a later commit, and still sitting in the git history where anybody cloning the repository can read it
    A key embedded in a browser bundle or a mobile binary because the team shipped without a backend proxy and told themselves it was temporary
    A key pasted into a chat channel to unblock a colleague, then retained indefinitely by a platform your firm does not control
    A production key on a laptop for local development, then present in a screen share, a support bundle, or a machine that leaves with a departing employee
    A key in a CI configuration variable that is readable by every contributor with permission to open a pull request
    One shared key across every environment and workload, so revocation is an outage and nobody revokes promptly
    Verbose HTTP logging enabled during an incident, capturing outbound headers in plaintext into a log store with broad internal access
    A key issued to a contractor for a three week engagement and never deactivated when the engagement ended

    If a key does leak, the sequence is short and should be rehearsed. Issue a replacement first, deploy it, verify it is carrying traffic, then deactivate the compromised key so that any further use returns 401. Then read the per key transaction log for the exposure window and answer the question that actually matters to a professional obligation: which queries were run on that key while it was out of your control, and whose matters do they touch. That question is not answerable at all without per key logging, which is why the logging is a control and not merely a billing convenience.

    A Standard Worth Holding

    None of this is exotic. It is the same discipline applied to payment credentials, which most engineering teams already accept without argument. The only reason it is applied less consistently to legal data is a mistaken belief that public records cannot be sensitive.

    They cannot be, in isolation. A judgment of a High Court is published and citable and belongs to everyone. But a pattern of retrieval is not a judgment. It is a description of what a firm is working on, for whom, and since when, assembled by the firm itself and stored behind one string. Treat the string accordingly: created once and captured into a secret manager immediately, held only on servers you control, scoped narrowly enough that revocation is cheap, rotated on a schedule you have practised, and monitored against a baseline somebody actually established.

    The provider side of this is visible and worth checking on any vendor you consider. Keys stored as bcrypt hashes with no recovery path. Two accepted header forms. Distinct 401 messages that tell you whether a credential was missing, malformed, unrecognised or deactivated. Per key transaction logging with sensitive values redacted before storage, and lastUsedAt updated on every call. Rate limit headers on every response and a 429 carrying a retry interval rather than leaving you to guess. Those details are documented in the endpoint reference, and the credit consumption that a stolen key would be spending is published at API pricing.

    Treat the key like work product

    A leaked court data key does not merely expose records that are largely public. It exposes which counterparties your firm researched, which provisions you pulled and when you started, and that is privileged strategy rather than data. Keep keys server side behind your own proxy, issue one per environment and per workload so revocation is narrow, rotate on a schedule you have rehearsed, and watch lastUsedAt and the per key transaction log against a baseline you established deliberately. CourtMesh stores keys only as bcrypt hashes with no recovery path, logs every call per key with sensitive values redacted, and returns a distinct 401 when a key has been deactivated. Header formats, error semantics and rate limit behaviour are documented in the endpoint reference, with an API overview.

    Explore CourtMesh
    APISecurityAuthenticationDevelopersBest Practices
    X LinkedIn