Fetching from multi-tenant collection returns empty

default discord avatar
2 weeks ago

Hey! I'm making a PoC with Payload as multi-tenant CMS for some Next frontends. My query for tenant-specific data returns an empty list, and so I'd just like to check that my thinking and setup is correct. I'm on localhost with my Payload backend (clone of multi-tenant example) and two Next frontends running on each their own port:

- The collection I'm querying is set up with a


field. I can logon as tenant admin and see other tenants' data filtered out.

- My tenants are set up with a


field, and their


field is set up with a test domain that is mocked in Windows hosts file. I'm querying the data like so:


- I have Payload config set up with

routes { api: "/cms/api" }

to let the Next apps use that route. Then I have nginx configured for each host domain to redirect


to the Next frontend and




to my Payload backend.

I'm accessing the frontends in my browser and trying to intercept the GET using Postman Interceptor. I don't know if it's the interceptor but the request doesn't show up. It catches everything on reload page, navigating in admin, etc.

I'm console logging the return value


though and it does return an empty list.

Any ideas welcome, thanks!


- Make sure the collection config

access: { read: anyone }

to make it publicly queryable

- Adding

depth: 2

to the query made it return data, finally.

However data from other tenants are returned as well so I keep looking.

Any ideas why tenant should not be respected in a query of thi?

  const query = {
    tenant: {
      slug: {
        equals: 'hjertets-tempel'

  const stringified = qs.stringify(
      depth: 2,
      where: query
      addQueryPrefix: true
  const url = http://hjertets-tempel.localhost/cms/api/courses${stringified}

Solved: The query is fine. It doesn't need


specified (not sure why it returned


before without it).

You can query collections publicly (without


headers identifying what


you are querying as), as long as your collection's

access: read

config resolves to


. In that case the query will return everything.

If you want to return only one tenant's data using the query pattern specified in the multi-tenant example,


, you have to authorize the query for Payload to be able to differentiate between tenant data.

Make sure the collection has a


field, and that each tenant has a



So you can authorize your app's requests and basically log in using the request headers, but a better way is using API keys, thanks August for letting me know:

- Add

auth: { useAPIKey: true }

to your



- Log in to your admin dashboard and enable API keys on the appropriate tenant admin user, copy the API key,

- Query the data from your app with the key as specified here:


That way you can let your apps interact with your backend as tenant admin users thru their API key.

Turns out the API key filters the tenant data already. I haven't been able to make the filter by query params work. Edit: I'm guessing it's meant to be used when you authorize the request normally (without API key).

    Open the post
    Continue the discussion in Discord
    Like what we're doing?
    Star us on GitHub!


    Connect with the Payload Community on Discord



    Can't find what you're looking for?

    Get help straight from the Payload team with an Enterprise License.