How to authenticate every request to the Passkallet BaaS API using your API key.

API Key Auth

How Authentication Works

Passkallet uses API key authentication. This is the simplest form of authentication -- you include a secret key in every request, and the server uses it to identify you and check your permissions.

There is no OAuth flow, no JWT tokens, no refresh tokens. Just one header on every request.

Your API key is hashed with SHA-256 and compared against stored hashes. Passkallet never stores your raw API key.

The x-api-key Header

Every request to the Passkallet BaaS API must include the x-api-key header:

x-api-key: pk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4

If you forget this header, you get:

json
{
  "statusCode": 401,
  "content": {
    "message": "Missing x-api-key header"
  }
}

If the key is wrong, you get:

json
{
  "statusCode": 401,
  "content": {
    "message": "Invalid API key"
  }
}

Full Example

bash
curl https://gateway.dev.passkallet.com/sepolia/api/v1/passkallet/baas/wallets \
  -H "x-api-key: pk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4"

Reusable client in Node.js:

javascript
const BASE = "https://gateway.dev.passkallet.com/sepolia/api/v1/passkallet/baas";

export function createPasskalletClient(apiKey) {
  async function request(path, options = {}) {
    const response = await fetch(`${BASE}${path}`, {
      ...options,
      headers: {
        "x-api-key": apiKey,
        "Content-Type": "application/json",
        ...options.headers,
      },
    });

    const data = await response.json();

    if (!response.ok) {
      const error = new Error(data.content?.message || "Passkallet API error");
      error.statusCode = data.statusCode;
      throw error;
    }

    return data.content;
  }

  return {
    get: (path) => request(path),
    post: (path, body) =>
      request(path, {
        method: "POST",
        body: JSON.stringify(body),
      }),
    patch: (path, body) =>
      request(path, {
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (path) => request(path, { method: "DELETE" }),
  };
}

Security Best Practices

Do This

  • Store API keys in environment variables (.env files)
  • Call the Passkallet API from your backend server, never from the browser
  • Use different API keys for development and production
  • Give each key the minimum scopes it needs
  • Rotate keys periodically and set expiration dates

Do NOT Do This

  • Do not put API keys in your frontend JavaScript code
  • Do not commit API keys to git repositories
  • Do not share API keys over email or chat
  • Do not give a key all scopes if it only needs read access

What Happens When Authentication Fails

Status CodeMeaningWhat to Do
401API key is missing, invalid, disabled, revoked, or expiredCheck that you are sending the x-api-key header with a valid, active key
403API key does not have the required scope(s)Check the key's scopes in your organization settings