Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.paxoslabs.com/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks through the full webhook setup: creating an endpoint in the Paxos Labs Console, writing a minimal receiver, and verifying the connection with a test event.

Prerequisites

  • A Paxos Labs organization with admin access
  • A publicly reachable HTTPS server (or a tunnel like ngrok for local development)

Step 1: Create a Webhook Endpoint

1

Open the Paxos Labs Console

Navigate to your organization in the Paxos Labs Console and select the Webhooks tab.
2

Add an endpoint

Click Add Endpoint. Enter your HTTPS URL, an optional display name, and select the event types you want to receive.
3

Save your signing secret

After creation, a signing secret starting with pxlwh_ is displayed once. Copy it immediately and store it in your secrets manager (e.g., AWS Secrets Manager, Vault, or .env for local development).
The signing secret is shown only at creation time. If you lose it, delete the endpoint and create a new one.

Step 2: Build a Receiver

Create a minimal HTTP server that accepts POST requests, verifies the signature, and responds with 200 OK.
import { createServer } from 'node:http'
import { createHmac, timingSafeEqual } from 'node:crypto'

const SECRET = process.env.WEBHOOK_SECRET       // pxlwh_...
const PORT   = process.env.PORT || 4000
const TOLERANCE_SECONDS = 300                    // 5-minute replay window

function verify(rawBody, signatureHeader, timestampHeader) {
  const timestamp = new Date(timestampHeader)
  if (Math.abs(Date.now() - timestamp.getTime()) / 1000 > TOLERANCE_SECONDS) {
    throw new Error('Timestamp outside tolerance')
  }

  const expected = createHmac('sha256', SECRET)
    .update(`${timestampHeader}.${rawBody}`)
    .digest('hex')

  const received = Buffer.from(signatureHeader, 'hex')
  if (!timingSafeEqual(received, Buffer.from(expected, 'hex'))) {
    throw new Error('Invalid signature')
  }
}

const server = createServer((req, res) => {
  if (req.method !== 'POST') {
    res.writeHead(405).end()
    return
  }

  const chunks = []
  req.on('data', (c) => chunks.push(c))
  req.on('end', () => {
    const rawBody = Buffer.concat(chunks).toString('utf-8')
    try {
      verify(
        rawBody,
        req.headers['x-paxos-labs-signature'],
        req.headers['x-paxos-labs-timestamp'],
      )
      const event = JSON.parse(rawBody)
      console.log(`Received ${event.type}${event.id}`)
      res.writeHead(200).end('ok')
    } catch (err) {
      console.error('Verification failed:', err.message)
      res.writeHead(401).end('unauthorized')
    }
  })
})

server.listen(PORT, () => console.log(`Listening on :${PORT}`))

Step 3: Expose Your Local Server

For local development, use a tunnel so Paxos Labs can reach your machine:
ngrok http 4000
Copy the generated https:// URL and use it as your webhook endpoint URL in the Paxos Labs Console.

Step 4: Send a Test Event

Back in the Paxos Labs Console, expand your endpoint row and click Send Test. Choose ping to fire a lightweight connectivity check. Your server should log output like:
Received ping — evt_test_a1b2c3d4-e5f6-7890-abcd-ef1234567890
If the delivery succeeds, the endpoint’s delivery history shows a Success badge with the HTTP status code. You’re ready to subscribe to real events.

Step 5: Subscribe to Events

Edit your endpoint to add event types like direct_transfer.deposit.pending, direct_transfer.deposit.confirmed, or direct_transfer.deposit.failed. When those events occur in your organization, your server will receive them automatically.

Next Steps

Signature Verification

Deep dive into the HMAC-SHA256 signature scheme, replay protection, and production best practices.

Event Catalog

Full reference of every event type with payload schemas and field descriptions.