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
designIdnamecreatedAtuserIddesign.updated
Fired when a design is modified
designIdnameupdatedAtchangesdesign.deleted
Fired when a design is deleted
designIddeletedAtuserIddesign.exported
Fired when a design is exported
designIdformatpresetexportUrldesign.shared
Fired when a design is shared
designIdshareIdshareUrlvisibilityelement.added
Fired when an element is added to a design
designIdelementIdtypepropertiesai.suggestion.applied
Fired when an AI suggestion is accepted
designIdsuggestionIdtypechangesPayload 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
- Learn about the REST API
- Explore MCP Protocol
- See Integrations