Docs SDK @holdify/express

@holdify/express

Express.js middleware for Holdify.

Installation

Terminal
bash
npm install @holdify/express

Quick start

app.ts
typescript
import express from 'express';
import { holdifyMiddleware } from '@holdify/express';

const app = express();

// Protect all /api routes
app.use('/api', holdifyMiddleware({
  apiKey: process.env.HOLDIFY_PROJECT_KEY,
}));

app.get('/api/data', (req, res) => {
  // Verification result available on req.holdify
  const { remaining, plan } = req.holdify;

  res.json({ data: 'protected', remaining });
});

app.listen(3000);

Configuration

Middleware options
typescript
holdifyMiddleware({
  // Required
  apiKey: process.env.HOLDIFY_PROJECT_KEY,

  // Optional: Custom API URL
  baseUrl: 'https://api.holdify.io',

  // Optional: Custom key extraction
  getKey: (req) => {
    return req.headers['x-custom-key'];
  },

  // Optional: Custom error handling
  onError: (error, req, res) => {
    res.status(error.statusCode || 500).json({
      error: error.code,
      message: error.message,
    });
  },

  // Optional: Success callback
  onSuccess: (result, req) => {
    console.log(`Verified: ${result.remaining} remaining`);
  },
});

Key extraction

By default, the middleware looks for API keys in:

  1. Authorization: Bearer <key> header
  2. x-api-key: <key> header
  3. ?api_key=<key> query parameter

Custom extraction:

Custom key extraction
typescript
holdifyMiddleware({
  apiKey: process.env.HOLDIFY_PROJECT_KEY,
  getKey: (req) => {
    // Your custom logic
    return req.headers['x-my-api-key'];
  },
});

Accessing verification result

Using req.holdify
typescript
app.get('/api/data', (req, res) => {
  // Always available after middleware
  const {
    valid,        // boolean
    remaining,    // number
    limit,        // number
    reset,        // unix timestamp
    plan,         // string
    entitlements  // string[]
  } = req.holdify;

  // Check entitlements
  if (req.holdify.entitlements?.includes('feature:premium')) {
    // Premium access
  }
});

Rate limit headers

The middleware automatically sets these headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when limit resets

Selective protection

Route-specific middleware
typescript
// Only protect specific routes
app.use('/api/protected', holdifyMiddleware({ apiKey }));

// Public routes (no middleware)
app.get('/api/public', (req, res) => {
  res.json({ public: true });
});

TypeScript

Type support
typescript
import type { Request } from 'express';
import type { VerifyResult } from '@holdify/express';

// req.holdify is typed
app.get('/api/data', (req: Request, res) => {
  const result: VerifyResult = req.holdify;
});