Skip to main content
PlaneConnection uses webhooks in two directions:
  1. Inbound webhooks — receive events from third-party services (Stripe, Resend)
  2. Outbound webhooks — send events to your own endpoints when things happen in the platform

Inbound Webhooks

Inbound webhooks use signature verification instead of session tokens.

Stripe Webhooks

Endpoint: POST /api/webhooks/stripe Receives Stripe payment events. Signature is verified using the stripe-signature header and a shared signing secret. Events handled:
EventAction
checkout.session.completedMarks invoices as paid
payment_intent.succeededUpdates payment status
customer.subscription.createdSyncs subscription status
customer.subscription.updatedSyncs subscription changes
customer.subscription.deletedMarks subscription as cancelled
invoice.paidUpdates subscription billing status
invoice.payment_failedFlags failed billing

Stripe Connect Webhooks

Endpoint: POST /api/webhooks/stripe-connect Receives events for Stripe Connect (multi-party payments, FBO onboarding, trip payment splits).

Resend Webhooks

Endpoint: POST /api/webhooks/resend Receives email delivery events from Resend for deliverability monitoring and email analytics. Signature is verified using the webhook signing secret. Events handled:
EventDescription
email.sentEmail accepted by Resend for delivery
email.deliveredEmail successfully delivered to inbox
email.bouncedEmail bounced (hard or soft)
email.complainedRecipient marked email as spam
email.clickedRecipient clicked a link in the email
email.openedRecipient opened the email
email.delivery_delayedEmail delivery is delayed
email.suppressedEmail suppressed (previous bounce/complaint)

Outbound Webhooks

You can configure outbound webhooks to receive notifications when events occur in your PlaneConnection workspace. Webhooks are managed via the API and require admin permissions.

Managing Webhooks

Base path: /api/v1/webhooks
MethodPathDescriptionRequired Role
GET/webhooksList webhooksAdmin/Manager
GET/webhooks/:idGet a webhook with recent logsAdmin/Manager
POST/webhooksCreate a webhookAdmin
PUT/webhooks/:idUpdate a webhookAdmin
DELETE/webhooks/:idDelete a webhook and its logsAdmin
POST/webhooks/:id/testSend a test eventAdmin/Manager

Create Webhook

curl -X POST "https://api.planeconnection.com/api/v1/webhooks" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Flight notifications",
    "url": "https://your-app.example.com/webhooks/planeconnection",
    "secret": "whsec_your_signing_secret",
    "events": ["flight.scheduled", "flight.departed", "flight.arrived"],
    "active": true,
    "retry_count": 3,
    "timeout_ms": 10000
  }'
Webhook URLs targeting private/internal networks (RFC 1918, loopback, link-local, metadata endpoints) are blocked to prevent SSRF attacks.

Webhook Configuration

FieldTypeRequiredDescription
namestringYesHuman-readable name (max 100 chars)
urlstringYesHTTPS endpoint to receive events
secretstringNoSigning secret for HMAC-SHA256 verification
eventsstring[]YesEvent types to subscribe to
activebooleanNoEnable/disable (default: true)
headersobjectNoCustom headers to include in deliveries
retry_countintegerNoMax retry attempts, 0-10 (default: 3)
timeout_msintegerNoRequest timeout, 1000-30000ms (default: 10000)

Signature Verification

When a secret is configured, each delivery includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the payload:
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
Verify the signature in your handler:
const crypto = require("crypto");

function verifyWebhook(payload, signature, secret) {
  const expected = crypto.createHmac("sha256", secret).update(payload).digest("hex");
  return `sha256=${expected}` === signature;
}

Delivery Headers

Every webhook delivery includes these headers:
HeaderDescription
Content-Typeapplication/json
X-Webhook-EventEvent type (e.g., flight.departed)
X-Webhook-TimestampISO 8601 delivery timestamp
X-Webhook-IDWebhook configuration ID
X-Webhook-SignatureHMAC-SHA256 signature (if secret configured)

Available Event Types

Query available event types at GET /api/v1/webhooks/events.

Reservations

EventDescription
reservation.createdNew reservation created
reservation.updatedReservation details updated
reservation.cancelledReservation cancelled
reservation.checked_inGuest checked in
reservation.checked_outGuest checked out

Billing

EventDescription
invoice.createdInvoice generated
invoice.paidInvoice payment received
invoice.overdueInvoice past due date

Flights

EventDescription
flight.scheduledFlight scheduled
flight.departedFlight departed
flight.arrivedFlight arrived
flight.cancelledFlight cancelled

Maintenance

EventDescription
maintenance.dueMaintenance item becoming due
maintenance.completedMaintenance completed

Customers

EventDescription
customer.createdNew customer profile created
customer.updatedCustomer profile updated

Delivery Logs

View webhook delivery history and troubleshoot failures. Endpoint: GET /api/v1/webhooks/logs
ParameterTypeDescription
webhook_idstringFilter by webhook ID
event_typestringFilter by event type
statusstringFilter by status: pending, success, failed
date_fromstringStart date filter
date_tostringEnd date filter
limitintegerMax results (default: 50, max: 100)
offsetintegerPagination offset

Test a Webhook

Send a test event to verify your endpoint is receiving deliveries:
curl -X POST "https://api.planeconnection.com/api/v1/webhooks/wh_abc123/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "flight.scheduled",
    "payload": {
      "id": "flt_test",
      "departure": "KJFK",
      "arrival": "KLAX"
    }
  }'
Last modified on April 11, 2026