Swipelux

Webhooks

Real-time notifications for verification, rail, and transfer events.

For complete API specification, see the API Reference.

Subscribe to webhook events to react to verification updates, rail status changes, and transfer state transitions in real time.

Configure webhooks

Set the destination URL on your merchant account. Webhooks are scoped per merchant — every event for any customer under that merchant is delivered to the same endpoint.

curl -X PATCH https://api.swipelux.com/v1/webhooks \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-server.com/webhooks"}'

Payload structure

Every delivery has the same envelope:

{
  "type": "event.type",
  "data": { /* event-specific */ },
  "createdAt": 1705312200000
}

createdAt is a Unix epoch in milliseconds.

Customer events

customer.verification_changed

Fired when a customer's KYC (individual) or KYB (business) verification status transitions.

{
  "type": "customer.verification_changed",
  "data": {
    "customerId": "cus_abc123",
    "customerType": "individual",
    "verificationStatus": "approved",
    "previousStatus": "pending",
    "reason": null
  },
  "createdAt": 1705312200000
}
FieldTypeDescription
customerIdstringCustomer ID
customerTypestringindividual or business
verificationStatusstringIndividual: not_started, pending, approved, rejected. Business: pending, approved, rejected.
previousStatusstring | nullStatus before this transition
reasonstring | nullSet when verificationStatus = rejected

customer.rail.status_changed

Fired when a rail's operational status transitions.

{
  "type": "customer.rail.status_changed",
  "data": {
    "customerId": "cus_abc123",
    "rail": "swift_named",
    "railStatus": "ready_to_use"
  },
  "createdAt": 1705312200000
}
FieldValues
railach_pooled, ach_named, fedwire_pooled, fedwire_named, sepa_pooled, sepa_named, swift_pooled, swift_named, pix_pooled, pix_named
railStatusrequested, ready_to_use, rejected

customer.rail.documents_requested

Fired when compliance has reviewed a rail and needs additional documents before approval. The railStatus is unchanged — collect the listed documents and re-submit.

{
  "type": "customer.rail.documents_requested",
  "data": {
    "customerId": "cus_abc123",
    "rail": "ach_named",
    "requiredDocuments": ["proof_of_address", "source_of_wealth"],
    "reason": "Address proof is older than 90 days"
  },
  "createdAt": 1705312200000
}

reason is optional. requiredDocuments lists Swipelux-defined document type identifiers — provider names are never exposed.

Transfer events

Transfer events cover both pay-ins and pay-outs. The customer is identified via onBehalfOf.

transfer.created

{
  "type": "transfer.created",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "state": "pending"
  },
  "createdAt": 1705312200000
}

transfer.updated

{
  "type": "transfer.updated",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "state": "processing"
  },
  "createdAt": 1705312200000
}

transfer.completed

{
  "type": "transfer.completed",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "state": "completed"
  },
  "createdAt": 1705312200000
}

transfer.failed

{
  "type": "transfer.failed",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "state": "failed"
  },
  "createdAt": 1705312200000
}

transfer.funded_partial

Fired when a pay-in receives funding below the expected amount.

{
  "type": "transfer.funded_partial",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "state": "funded_partial"
  },
  "createdAt": 1705312200000
}

transfer.amount_adjusted

Fired when the booked amount diverges from the quoted amount (FX drift, fee adjustments, partial settlement).

{
  "type": "transfer.amount_adjusted",
  "data": {
    "id": "tr_xyz789",
    "onBehalfOf": "cus_abc123",
    "from": "100.00",
    "to": "95.50"
  },
  "createdAt": 1705312200000
}

Event reference

EventDescription
customer.verification_changedKYC / KYB status transition
customer.rail.status_changedRail status transition
customer.rail.documents_requestedCompliance needs more docs for a rail
transfer.createdTransfer initiated
transfer.updatedTransfer state transition (non-terminal)
transfer.completedTransfer reached completed
transfer.failedTransfer reached failed
transfer.funded_partialPay-in funded below expected amount
transfer.amount_adjustedBooked amount diverged from quoted amount

Security

Webhooks are signed with HMAC-SHA256. Verify the X-Webhook-Signature header before trusting any payload:

const crypto = require('crypto');
 
function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}