invokeRPC API during key generation returns {"error": {"code": -1, "message": "Unauthorized"}}}

I am having issue with the response being returned from invokeRPC API. This is the error message we are getting:

{“success”: true, “message”: “OK”, “rpcResponse”: {“error”: {“code”: -1, “message”: “Unauthorized”}}}

After changing the apiKey to SIGNER_KEY, attached is the error message we are getting:

Hi Kenna,
This is Mohammed from Fireblocks.
The key generation has to be done from an end-user device.
Please check out this comment about testing using POSTMAN

Thank you @mnamakwala.

"rpcResponse": {
"error": {
"message": "Unauthorized",
"code": -1

This error what will get using the frontend (I attached frontend codes segment). The backend API logic that is returning the error is fireblockSdk.signer.NCW.invokeWalletRpc. We used secretKey and signer_key from sanbox.

Please provide the workspace name and the first 4 digits of the API key being used?

@mnamakwala workspace name - Octoprime, API key (first 4 digit) - 6126…

Please double check how you initialize the Fireblocks API Client.
First, your API key does not start with “6126”, the first digits are “c6126” so there’s a “c” missing.
Second, make sure you pass the full API key (mentioned above) and the full private key. The private key should be one single string i.e. “-----BEGIN PRIVATE KEY-----\nMI…”

Hi @golan,

Thank you for your response. Yes the API key starts with “c”. You asked for the first 6 digits that is why we omitted the “c”. I have attached the snapshot of the begining our private key for your attention. We used as compied (we did not edit it)

This is how we initialized the fireblock API client

const { FireblocksSDK } = require(‘fireblocks-sdk’);
const fireSignerInstance = () => {
const dirPath = path.resolve(__dirname, ‘…/keys’);
const apiSecret = fs.readFileSync(path.join(dirPath, ‘fireblocks_admin_secret.key’), ‘utf8’);

const apiKey = process.env.FIREBLOCKS_API_SIGNER_KEY
const fireblocks = new FireblocksSDK(apiSecret, apiKey, process.env.FIREBLOCKS_BASE_URL);

return fireblocks;


Please try replacing ending lines with ‘\n’ i.e.

let apiSecret = fs.readFileSync(path.join(dirPath, 'fireblocks_admin_secret.key'), 'utf8');
apiSecret = apiSecret.replace(/\n/g, '\\n');

Hi @golan,

This is the error we get at the frontend after API call to the backend. The error we get on the frontend console is pasted below. Same thing we got when we tried it on postman in the attached image.

 "url": "",
 "token": "eyJhbGciOiJIUzkpXVCJ9.eyJ1c2G5vbGFuemlwLmNvbSIsImlhdCI6MTcxOTkxMjgwNzE5OTE2NDA1fQ.FmDDzB5LOL_zamC5AIoR9Db3YD4pxdFXM",
 "postData": {
  "deviceId": "515ffcce-d8ce-4f22-9730-7d39ee236911",
  "mpcMessage": "{\"method\":\"get_service_certificates\",\"headers\":{\"platformType\":\"iOS\",\"physicalDeviceId\":\"fada0fc8-a6bd-4581-837c-ea177451ab88\",\"mpcVersion\":\"6\",\"sdkVersion\":\"2.6.0\"}}",
  "userId": ""
 "method": "POST"

How do you call the FB BE from your BE?
Can you share your code?
Should be something like:

return await signer.NCW.invokeWalletRpc(

@golan, this is it.

const { userId, deviceId, mpcMessage } = req.body;
const fireSigner = utilities.fireSignerInstance();

const invokedRPC = await fireSigner.NCW.invokeWalletRpc(account.walletId, deviceId, JSON.stringify(mpcMessage));
console.log(`invokedRPC: ${JSON.stringify(invokedRPC)}`);

Could you explain what the payload from Fireblocks to Backend represent in the diagram below?

Do you mean the webhook paylod?
You can read our webhook documentation here

As for the 401 errors, we do not see any of the failures you mentioned.
Please provide more information:

  • The approximate time the API call was performed
  • The requestId from the response headers if it exists.
  • The fireblocks BE hostname you are using.

Also, please try to call another API, a non-NCW one, to see if you still have an 401 error, e.g. getTransactions


  • The approximate time the API call was performed - The response time is immediate.
  • The requestId from the response headers if it exists. - NA
  • Hostname - fireblockInstance.NCW.invokeWalletRpc (fireblockInstance was created using Signer Api_key from our Sandbox workspace)

See below the steps from Frontend to Backend, and let us know if we missed anything.

  • await FireblockService.AssignDevice() - Frontend
  • await initFireblocksNCW() - Frontend
  • await fireblocksNCW.generateMPCKeys() - Frontend
  • await fireSigner.NCW.invokeWalletRpc (walletId, deviceId, strPayload) - Backend

initFireblocksNCW instance (frontend) is created by:

fireblocksNCW = await FireblocksNCWFactory({
          logLevel: "INFO",

fireSigner instance (backend) is created as:

    const dirPath = path.resolve(__dirname, '../keys');
    let apiSecret = fs.readFileSync(path.join(dirPath, 'fireblocks_admin_secret.key'), 'utf8');
    apiSecret = apiSecret.replace(/\\n/g, "\n");

    const apiKey = process.env.SIGNER_API_KEY
    const fireblocks = new FireblocksSDK(apiSecret, apiKey, process.env.FIREBLOCKS_BASE_URL);
    return fireblocks;

Finally, getTransactions worked fine but the apiKey used is that of the admin (i.e., apiKey = process.env.ADMIN_API_KEY).

This is the final error messages that is seen at the frontend.

ERROR  Request failed with status code 401
 LOG  DEBUG : Error Headers: 
 "access-control-allow-headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization",
 "access-control-allow-methods": "GET, POST, PATCH, DELETE",
 "access-control-allow-origin": "*",
 "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
 "content-length": "65",
 "content-type": "application/json; charset=utf-8",
 "date": "Tue, 09 Jul 2024 11:20:43 GMT",
 "etag": "W/\"41-DXEuJgo1HyxuYzoDNTCOnBUGE0g\"",
 "function-execution-id": "a9ssh192ud7o",
 "server": "Google Frontend",
 "x-cloud-trace-context": "9019bc977c620559757990ab87eb5996",
 "x-powered-by": "Express"
 LOG  [AxiosError: Request failed with status code 500] SendMessage error

You are using fireblocks_admin_secret.key for the FireblocksSDK instance of SIGNER_API_KEY.
Is this correct? How did you create the NCW_SIGNER user?
Did you use the fireblocks_admin_secret.key and its corresponding CSR?

You can also try to create a new NCW SIGNER user.
It should work for getTransactions as well as the admin user.

Thanks @golan. The issue is resolved now. It was caused because I was using the same secret key for both admin and signer.