API Reference

Webhooks

Receive real-time notifications when events occur in Platphorm Design. Configure webhooks to integrate with your workflows and automations.

Overview
How webhooks work in Platphorm Design
┌─────────────────────────────────────────────────────────────────────┐
│                       WEBHOOK FLOW                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  Event Occurs           Webhook System           Your Endpoint       │
│       │                      │                        │              │
│  [User exports      ──▶  [Queue event]          [Receive POST]       │
│   a design]               │                        │                 │
│                      [Sign payload]           [Verify signature]     │
│                           │                        │                 │
│                      [POST to your    ──▶    [Process event]        │
│                       endpoint]                    │                 │
│                           │                   [Return 200]           │
│                      [Mark delivered]  ◀──        │                 │
│                                                                      │
│  Retry policy: 3 attempts with exponential backoff                   │
│  Timeout: 30 seconds per attempt                                     │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
Configuration
Register and manage webhook endpoints
// POST /api/v1/webhooks

const response = await fetch('/api/v1/webhooks', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-PlatPhorm-API-Key': '$PLATPHORM_API_KEY'
  },
  body: JSON.stringify({
    url: 'https://your-app.com/webhooks/platphorm',
    events: [
      'design.created',
      'design.exported',
      'design.shared'
    ],
    secret: 'your-webhook-secret', // Optional, auto-generated if omitted
    description: 'Production webhook for design events',
    active: true
  })
})

const webhook = await response.json()
// {
//   id: "wh_abc123",
//   url: "https://your-app.com/webhooks/platphorm",
//   events: ["design.created", "design.exported", "design.shared"],
//   secret: "whsec_...", // Use this to verify signatures
//   active: true,
//   createdAt: "2024-01-15T10:00:00Z"
// }

Event Types

design.created
Fired when a new design is created
designIdnamecreatedAtuserId
design.updated
Fired when a design is modified
designIdnameupdatedAtchanges
design.deleted
Fired when a design is deleted
designIddeletedAtuserId
design.exported
Fired when a design is exported
designIdformatpresetexportUrl
design.shared
Fired when a design is shared
designIdshareIdshareUrlvisibility
element.added
Fired when an element is added to a design
designIdelementIdtypeproperties
ai.suggestion.applied
Fired when an AI suggestion is accepted
designIdsuggestionIdtypechanges
Payload Structure
Webhook payload format and examples
interface WebhookPayload {
  // Event identification
  id: string           // Unique delivery ID
  type: string         // Event type (e.g., "design.exported")
  timestamp: string    // ISO 8601 timestamp
  
  // API version for backwards compatibility
  apiVersion: string   // e.g., "2024-01-01"
  
  // Event-specific data
  data: {
    // Varies by event type
    [key: string]: unknown
  }
  
  // Metadata
  metadata: {
    source: "platphorm-design"
    environment: "production" | "staging"
    userId?: string
    designId?: string
  }
}
Signature Verification
Verify webhook authenticity using HMAC signatures
import crypto from 'crypto'

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex')
  
  const signatureBuffer = Buffer.from(signature.replace('sha256=', ''), 'hex')
  const expectedBuffer = Buffer.from(expectedSignature, 'hex')
  
  return crypto.timingSafeEqual(signatureBuffer, expectedBuffer)
}

// In your webhook handler
export async function POST(request: Request) {
  const signature = request.headers.get('X-Platphorm-Signature')
  const payload = await request.text()
  
  if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return new Response('Invalid signature', { status: 401 })
  }
  
  const event = JSON.parse(payload)
  // Process event...
  
  return new Response('OK', { status: 200 })
}
Retry Policy
Automatic retry behavior for failed deliveries
// Retry schedule (exponential backoff)
// Attempt 1: Immediate
// Attempt 2: 1 minute after first failure
// Attempt 3: 5 minutes after second failure
// Attempt 4: 30 minutes after third failure (final)

// A delivery is considered failed if:
// - Response status is not 2xx
// - Connection timeout (30 seconds)
// - SSL/TLS error
// - DNS resolution failure

// After 4 failed attempts:
// - Webhook is marked as "failing"
// - Alert email sent to account owner
// - Webhook remains active for future events

Timeout

30 seconds per attempt

Max Attempts

4 attempts total

Success Response

Any 2xx status code

Idempotency

Use delivery ID to dedupe

Delivery Logs
View and debug webhook deliveries
// GET /api/v1/webhooks/:id/deliveries

const response = await fetch('/api/v1/webhooks/wh_abc123/deliveries', {
  headers: { 'X-PlatPhorm-API-Key': '$PLATPHORM_API_KEY' }
})

const deliveries = await response.json()
// {
//   deliveries: [
//     {
//       id: "evt_abc123",
//       event: "design.exported",
//       timestamp: "2024-01-15T14:30:00Z",
//       status: "success",
//       responseStatus: 200,
//       responseTime: 234,
//       attempts: 1
//     },
//     {
//       id: "evt_def456",
//       event: "design.created",
//       timestamp: "2024-01-15T12:00:00Z",
//       status: "failed",
//       responseStatus: 500,
//       responseTime: 1250,
//       attempts: 4,
//       lastError: "Internal Server Error"
//     }
//   ]
// }

// Retry a failed delivery manually
await fetch('/api/v1/webhooks/deliveries/evt_def456/retry', {
  method: 'POST',
  headers: { 'X-PlatPhorm-API-Key': '$PLATPHORM_API_KEY' }
})
Best Practices
Tips for reliable webhook integration

Respond Quickly

Return a 200 response immediately, then process the event asynchronously. Long processing times can cause timeouts and retries.

Handle Duplicates

Use the delivery ID to detect and handle duplicate events. Retries may deliver the same event multiple times.

Verify Signatures

Always verify the webhook signature before processing. This prevents accepting forged requests.

Use HTTPS

Webhook endpoints must use HTTPS. HTTP endpoints are rejected for security reasons.

Related Documentation