Docs/Framework integrations

Find the framework route, component prop, SDK method, or HTTP contract you need.

Express

Mount the proxy as standard Express middleware. Mount webhook verification before JSON parsing so the adapter receives the original request bytes.

Create the integration

import { createIncld, defineActions } from "@incld/client/express"

export const incld = createIncld({
 apiKey: process.env.INCLD_SECRET_KEY!,
 webhookSecret: process.env.INCLD_WEBHOOK_SECRET!,
 actions: defineActions({ sync_contacts: { run: runContactSync } }),
async resolveContext(_request, req) {
  if (!req.user) return null
  if (!req.organization) return null
  return {
   user: { id: req.user.id },
   organization: { id: req.organization.id },
   roles: req.user.roles,
  }
 },
 async authorize({ context, operation }) {
  return permissions.allow(context.user.id, operation)
 },
})

Mount proxy and webhook middleware

import express from "express"
import { incld } from "./incld"

const app = express()

// Mount before the global JSON parser so the signature sees exact bytes.
app.post(
 "/api/incld/webhook",
 express.raw({ type: "application/json" }),
 incld.webhook,
)

app.use(express.json())
app.use("/api/incld/v1", requireSession, incld.routes)

Middleware order matters

If a JSON parser consumes and reserializes the webhook body first, the HMAC will not match. The proxy may use parsed JSON; the webhook must retain the raw bytes.

Error handling

The middleware sends the adapter response status, headers, and body. Unexpected adapter exceptions are passed to Express next(error) when available. Keep your standard final error middleware after the @incld routes.

Synchronize actions on deploy

// scripts/sync-incld-actions.ts
import { incld } from "../src/incld"

await incld.syncActions()