How to distinguish request between LocalAPI and REST API in field hooks?

default discord avatar
Nikichlast year

Hello there! I'm digging deeper and deeper into PayloadCMS and I'm totally in love with it but still have some questions.

What I'm trying to achieve:

I'm developing integration via plugin to third-party CRM, and admin have to fill text fields with data (client secret keys, etc). After he had submitted this form I acquire access and refresh token (which are hidden in admin UI), I want to show empty values or '


' in admin UI for everyone but still be able to retrieve this values from LocalAPI.

I came up with next idea (field hook):

hooks: {
  afterRead: [
    args => {
      if (args.req.headers['x-payload-localapi']) {
        return args.value;

      return 'The value of this field is visible only for developers.';

It works fine for admin UI, but I get

Cannot read properties of undefined (reading 'x-payload-localapi')

while retrieving values through LocalAPI.

Is there another way to do so?

I see there is


property, but when I refresh admin UI it still says


... 🤔

So, basically I want to let users fill value once and it's gone for them, but not for developers, who can access it via LocalAPI.

Maybe I'm looking to the wrong way...

  • discord user avatar
    last year

    you should use access control here



    property is definitely working properly, but you might be seeing it run as


    if you have hooks or similar that run and then retrieve a doc via local api

    but if i were you, i'd use field-level access control. if you think about this, that's really what you are needing to do - - you need to restrict access to certain fields for your users

    so maybe


    and / or


    access control should be utilized, letting them


    the value(s), but then not update them

    you could certainly also use field-level hooks to


    the values, but the best way in that function would be to look at the


    instead of a header

    so at that point you'd have an access control idea running in a hook

  • default discord avatar
    Nikichlast year

    Do field level hooks fire after collection's hooks?



    sounds like a good idea, thanks! 🙂

    If I use access something like this

    { read: () => false }

    , then this field is hidden in UI even if I create new collection value.

    Hm, looks like I have to introduce new role


    and check that role in


    prop if

    req.user.role === Role.Developer

    then show real DB values, in any other cases mangle them.

  • discord user avatar
    last year

    you should look at the operation code within Payload to get a handle on what runs when. We will be adding more lifecycle-based info to our docs, but until then, looking at the operation code is the best bet

    that sounds right to me

Star on GitHub


Chat on Discord



Can't find what you're looking for?

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