Skip to main content

Why This Matters

Most production Lamina integrations should use webhooks instead of tight polling loops. The local CLI can now do the same thing:
  • start a local webhook receiver
  • verify Lamina’s ED25519 signature
  • expose the listener through ngrok or another public tunnel
  • run a real app against that callback URL

Lamina Webhook Contract

When you start an execution with:
Lamina sends a signed POST when the execution finishes. Headers:
  • X-Lamina-Webhook-Signature
  • X-Lamina-Webhook-Timestamp
  • X-Lamina-Webhook-Request-Id
Message to verify:
Verification key source:
The CLI listener and MCP listener both verify this contract directly.

Start A Local Listener

From the repository root:
That starts a local receiver at:

Expose It Publicly

Use ngrok, cloudflared, or your preferred tunnel. Example with ngrok:
If the public URL is https://example.ngrok.dev, save it as the default Lamina webhook URL:
The CLI normalizes that to:
Check what is saved:
Clear it if needed:

Run An App Against The Saved Webhook URL

You can also pass the public URL directly:

Expected Listener Output

For a successful callback, the listener prints a verified execution message like:
If verification fails, the listener rejects the callback and prints the verification error instead.

Real End-To-End Flow

1

Authenticate the CLI

Run lamina login (browser OAuth) or lamina login --api-key lma_... for CI.
2

Start the local listener

Run lamina webhook listen --port 8788.
3

Expose the listener

Start ngrok or another tunnel and get a public HTTPS URL.
4

Save the public webhook URL

Start the listener with --public-url ... --save-default, or pass the full webhook URL directly when you run the app.
5

Run the app

Execute lamina run <appId> --file inputs.json --webhook default.
6

Receive and verify the callback

The local listener validates the Lamina signature and prints the completed execution.

MCP Uses Polling Instead

The hosted and local MCP servers intentionally expose only five high-level creative tools. They do not expose webhook listener management tools. For MCP clients, start work with lamina_create and retrieve results with lamina_status. Use REST webhooks when you are building a server-side integration that owns a public callback URL.

Fallback

If you do not want to expose a callback during local development, omit ?webhook= and use polling with: