request headers from inside a custom database adapter
I'm creating a custom adapter, and i'd like to know if it's possible to access the headers of the request from the adapter ? I have a header for the url of the db of the tenant, placed by a middleware, so before that better-auth gets the request. I'm building a database adapter for postgREST (use fetch calls to communicate with a db pg) and i'd like to use the request's headers so that better-auth communicates to the right database, thus supporting multi tenancy without breaking better-auth's inner processes... @Better Auth
8 Replies
At the moment, the custom adapter’s function doesn’t receive the raw HTTP request or its headers directly—instead, it’s provided with parameters such as options, schema, debugLog, and a few helper functions [4]. This means that if you need to route your calls based on tenant-specific headers (like your database URL), you’ll need to capture that information in an earlier stage.
A common approach is to use a middleware or hook (see the Hooks documentation [1]) to extract your tenant header and then pass the necessary information (such as the tenant’s database connection string) into your Better Auth context or configuration. In this way, your adapter logic can reference this configuration value without having to directly access the request headers.
Does this approach sound like it might work for your multi-tenant implementation, or would you like to discuss additional options on how to propagate tenant-specific details further in the lifecycle?
Sources:
[1] Hooks | Better Auth
[4] Create a Database Adapter | Better Auth
— Better Auth is powered by https://clarm.com
Hooks | Better Auth
Better Auth Hooks let you customize BetterAuth's behavior
Create a Database Adapter | Better Auth
Learn how to create a custom database adapter for Better-Auth
you just said "A common approach is to use a middleware or hook (see the Hooks documentation [1]) to extract your tenant header and then pass the necessary information (such as the tenant’s database connection string) into your Better Auth context or configuration. In this way, your adapter logic can reference this configuration value without having to directly access the request headers."
I don't get how it would look like in code @Better Auth
Below is an example that shows how you could use a before hook to extract a tenant header from the request and inject the tenant’s configuration (for example, a database connection string) into the auth context. This way, your adapter can later read the tenant-specific configuration without needing direct access to the request headers.
In this example, the before hook extracts the tenant ID from the incoming request header
"X-Tenant-ID". It then uses a helper function to get the tenant configuration and merges it into the current auth context. Thislets later parts of your adapter logic access this information via something like
ctx.context.tenantConfig without directly interacting with the request headers [1].
Does this clarify how you could structure your code? Are there any additional details on tenant configuration or context modifications you’d like to explore further?
Sources:
[1] Hooks | Better Auth
— Better Auth is powered by https://clarm.comHooks | Better Auth
Better Auth Hooks let you customize BetterAuth's behavior
@Better Auth But you just said that i couldn't access the ctx from the adapter, so what you proposed me doesn't really help
It sounds like there’s some confusion about where and how the context (ctx) is available. In Better Auth, most of our adapter functions are expected to be called with a context provided by the middleware. For example, when using our DB hooks in the organization plugin, we now ensure that the correct ctx is passed from the routes to the adapter calls [2]. Similarly, our auth middleware gives you access to properties like cookies and secrets via ctx.context, as shown in our Hooks documentation [3].
If you’re seeing an issue where you “can’t access the ctx” from your adapter, it might be due to one of the following:
- The adapter call is being made outside the middleware flow, so ctx isn’t available in that scope.
- The custom adapter you’re using might not yet properly implement the expected interface that accepts ctx.
- There might be a mismatch in the adapter version you’re using versus the documentation.
Could you share more details about how you’re invoking your adapter method and what your adapter’s implementation looks like? That way, we can help pinpoint the issue and ensure you get the intended context. Have you checked if using the latest version of Better Auth (and its middleware) helps with this issue?
Sources:
[2] fix(organization): pass
ctx to DB hooks
[3] Hooks | Better Auth
— Better Auth is powered by https://clarm.comGitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.

GitHub
fix(organization): pass
ctx to DB hooks by ping-maxwell · Pull R...closes #4767
Summary by cubic
Pass the request context (ctx) to session updates in the organization plugin so DB hooks run with the correct context. Fixes missing context in setActiveOrganization...
Hooks | Better Auth
Better Auth Hooks let you customize BetterAuth's behavior
@Better Auth i've looked into all the database adapter and none of them uses the ctx.
You're right that in many of our built‐in adapters you won't see an explicit ctx passed around in every function. Better Auth now wraps requests in a DB transaction that provides a request-scoped adapter context via AsyncLocalStorage [1]. This means internal calls—such as those in session updates or organization flows—receive the proper context without needing you to manually pass ctx everywhere [7]. Additionally, many adapter methods are designed to work directly with the context provided by Better Auth (for example, through internal adapter functions and hooks) so that custom adapter implementations don't have to plumb ctx manually unless you need to extend functionality [10].
Are you looking to build a custom adapter or encountering issues with a particular adapter function?
Sources:
[1] feat: enable db transaction during api call by default
[7] fix(organization): pass
ctx to DB hooks
[10] Hooks | Better Auth
— Better Auth is powered by https://clarm.comGitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.

GitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.

GitHub
feat: enable db transaction during api call by default by himself65...
Fixes: #4554
Summary by cubic
Wraps all auth requests in a DB transaction and provide a request-scoped adapter context using AsyncLocalStorage. This makes writes atomic per request and lets downst...
GitHub
fix(organization): pass
ctx to DB hooks by ping-maxwell · Pull R...closes #4767
Summary by cubic
Pass the request context (ctx) to session updates in the organization plugin so DB hooks run with the correct context. Fixes missing context in setActiveOrganization...

