A user of Jenkins can define a folder and then an job in that folder. Or there can be a ComputedFolder, like a multibranch project that generates jobs for each branch in a version control system. If the user then adds credentials to the folder, those credentials should be available to the jobs that are in that same folder or in a child folder of it. This does not work with your code, which passes Jenkins.get() as the ItemGroup when it calls lookupCredentials. If you have a Run, you can call Run.getParent() to get a Job that you can then pass in as an Item to another overload of lookupCredentials. That way, lookupCredentials will be able to search for credentials in the correct folder.
However, findCredentialById uses the authorization of the Job rather than ACL.SYSTEM, which you were using. This has two consequences if you start using findCredentialById:
You should also change the configuration UI so that it won’t let the user choose a credential that would cause an error later because the job is not authorized to use it.
Users have to configure the credentials such that jobs can access them. This will let pipeline jobs use credential binding to read the secrets, so people who can edit such pipelines can find out those secrets. If the credentials are generally defined by Jenkins administrators and have high access to https://api.redpen.ai then maybe it’s a bad idea to force them to be disclosed to owners of pipelines in that way.
If your code is running in the context of a build, it is better to use the methods which actually take Run. I think this has some impact when using user-scoped credentials, though I do not understand that clearly. It also means that you can use OpenID Connect Provider to pass an id token with build-specific claims, for example.