Your Clio integration worked yesterday. Today the token exchange returns 401 invalid_client with the same client id and the same secret. Nothing in your code changed, nothing in Clio's status page is red, and the error is telling you something that is not true: the client is fine.
What expired is the account. A Clio Manage trial carries API access for about seven days. After that the authorize step still works, still opens the consent screen, and still hands back a code. It is the exchange of that code for a token that fails, which is the worst possible place for it to fail, because everything up to that point looks like success.
We hit this on 1 September 2026 while building against a trial. The cost was not the outage. It was the day spent proving the credentials were correct, which they were the whole time.
What the seven-day window actually gates
The distinction that matters, and the one the error hides: the gate is the account type, not the plan tier. It is tempting to read invalid_client on a trial as a nudge to buy something. It is not. A trial that has passed its API window will keep returning invalid_client on a higher tier, because what lapsed is the trial's API entitlement, not a feature sitting behind a price.
The account you want is a Clio developer account, and it is free. If you are evaluating Clio's API and reach for a plan to fix this, you will spend money and still be locked out.
The short version: if /token starts returning invalid_client roughly a week into a trial, stop debugging your credentials. Convert the account.
Why the error tells you nothing
Clio answers invalid_client for every OAuth failure it has. We tested the permutations against the same account in one sitting:
- A deliberately wrong client secret
- The correct client secret, on an account past its API window
- Credentials in the request body rather than as HTTP Basic auth
- An authorization-code grant
- A refresh-token grant
Every one of them: HTTP 401, invalid_client, no further detail in the body.
That has a consequence worth stating plainly, because it invalidates a pattern people reach for. You cannot build a credential pre-check on this endpoint. A setup wizard that tries the token endpoint and reports "those credentials look wrong" will say exactly the same thing to a firm whose credentials are perfect and whose trial has lapsed. Only a completed sign-in proves a credential is good.
If you are writing onboarding for other people's Clio apps, treat a failed exchange as unclassified. Say the sign-in did not complete and list the candidates, rather than picking one and being confidently wrong.
Getting a developer account
Clio emails an intake form when a trial reaches its end, and that is the intended route. If the mail is gone or the window already closed, write to api@clio.com and ask for a developer account against the same login. No charge, no plan.
Register one app per region
A Clio developer app belongs to a region. If you intend to support firms on more than one of the US, EU, Australian or Canadian servers, register an app per region, ideally under separate addresses such as developer+us@ and developer+eu@. Retrofitting this later means re-registering redirect URIs while something is already in production. The Australian region and Canadian region both have their own endpoints and their own reasons a firm will insist on them.
Ruling out the cheaper causes first
Before you conclude the account is the problem, two things fail earlier in the flow and cost less to check.
The redirect URI is matched as a literal string. No trailing slash where you did not register one. 127.0.0.1, not localhost. And the port in your configuration has to be the port in the registered URI. Our Clio MCP setup guide walks both traps in detail, and they are by far the more common reason a first-time integration never completes.
The tell that separates them: a redirect mismatch usually fails at the redirect, before you hold a code. The entitlement problem lets you get all the way to a code and dies at the exchange. If you have a code in your hand and the exchange is refusing it, you are in the case this post is about.
What to do about it in code
Two changes are worth making whatever the cause turned out to be.
Do not let a token failure look like a credential verdict. Log the status and the error code, and phrase the user-facing message as an unclassified failure with candidates.
// Wrong: the endpoint cannot support this claim.
if (err.error === "invalid_client") throw new Error("Check your client secret.");
// Better: report what happened, list what it could be.
if (res.status === 401) {
throw new Error(
"Clio refused the token exchange (invalid_client). This is returned for a wrong " +
"secret, for correct credentials on an account without API access, and for a " +
"malformed request. If the account is a trial older than about a week, that is " +
"the most likely cause."
);
}
Fail loudly at startup on missing configuration, so a missing variable never presents as an auth failure later. Validating required credentials for the mode you are running in turns one class of mystery into a message at boot.
Frequently Asked Questions
Why does the Clio API return invalid_client when my client ID and secret are correct?
The most likely cause is that the Clio account behind the app is a trial whose API window has closed. A Clio Manage trial carries API access for about seven days. After that the authorize step still works and still hands you a code, and the token exchange returns HTTP 401 with invalid_client, using credentials that were valid the day before. Clio returns invalid_client for every OAuth failure it has, so the error cannot tell you which one you are hitting. The fix is a free developer account rather than a paid plan.
Does upgrading my Clio plan restore API access?
No. The gate is the account type, not the plan tier. A trial that has passed its API window will keep returning invalid_client on a higher tier, because what expired is the trial's API entitlement rather than a feature attached to a price. Converting the same account to a Clio developer account restores it, and that conversion is free.
How do I get a free Clio developer account?
Clio emails an intake form when a trial reaches its end, and that form is the intended path. If the mail has been lost or the window has already closed, write to api@clio.com and ask for a developer account for the same login. There is no charge and no plan to buy. Register one developer app per Clio region you intend to support, ideally under separate addresses, because an app belongs to a region.
Can I use the invalid_client error to debug my credentials?
No, and this is what makes it expensive. Clio answers invalid_client for a wrong secret, a correct secret against an ineligible account, credentials sent in the request body rather than as Basic auth, and an authorization-code grant as readily as a refresh-token grant. The response body does not distinguish them. Only a completed sign-in proves a credential is good, so credential checks that rely on reading this error will report confident nonsense.
What else returns an OAuth error that looks like this on Clio?
A redirect URI that does not match the registered value character for character, including the trailing slash and 127.0.0.1 rather than localhost, and a port in your configuration that disagrees with the port in the registered URI. Those fail at a different point in the flow and are worth ruling out first because they are cheaper to check. Our Clio MCP setup guide covers both in detail.
Next step
We maintain an open-source Clio connector for Claude, which is where this bit us. If you are building a Clio integration and want the traps documented rather than discovered, the rate limits and batch design and custom field posts cover the two that cost us the most after this one. If you would rather not build it at all, we do this for firms.