Versioning
As your API evolves, your webhook payloads need to change too. Von's versioning system lets you make changes without breaking existing integrations.
The Problem
Without versioning, changing a webhook payload breaks all existing consumers:
// v1: Original payload
{ "line_items": [...] }
// v2: Renamed field
{ "items": [...] } // ❌ Breaks existing integrations
The Solution
With Von versioning, each endpoint subscribes to a specific version. Von transforms payloads automatically:
Your App → Von → Transform → Endpoint
(v2 payload) (to v1) (receives v1)
- New endpoints get the latest schema
- Old endpoints continue receiving their subscribed version
- No coordination required with your customers
Creating Versions
Versions are identified by date strings (e.g., 2025-01-15). Each version can define transforms for specific event types.
Version Configuration
Each version specifies:
- Version ID - Date-based identifier
- Event Type - Which events to transform
- Transforms - How to modify the payload
Transform Types
rename- Rename fieldsremove- Remove fieldsdefaults- Add default values
import { Von } from "@usevon/sdk";
const von = new Von({
apiKey: process.env.VON_API_KEY,
});
// Create a version with transforms
await von.versions.post({
version: "2025-01-15",
eventType: "order.created",
transforms: {
rename: { line_items: "items" },
remove: ["legacy_id", "internal_notes"],
defaults: { api_version: "2025-01-15" },
},
});
Transform Examples
Renaming Fields
When you rename a field in your payload:
transforms: {
rename: {
line_items: "items", // line_items → items
customer_id: "customerId", // snake_case → camelCase
}
}
Input (v2):
{ "items": [...], "customerId": "cus_123" }
Output (v1):
{ "line_items": [...], "customer_id": "cus_123" }
Removing Fields
When you add fields that old versions shouldn't receive:
transforms: {
remove: ["internal_metadata", "debug_info"]
}
Adding Defaults
When old versions expect fields that new payloads don't include:
transforms: {
defaults: {
api_version: "2024-01-01",
currency: "USD"
}
}
Assigning Versions to Endpoints
Each endpoint can specify which version it wants:
// Create endpoint with specific version
await von.endpoints.post({
url: "https://customer.com/webhooks",
version: "2024-01-01", // Will receive v1 payloads
});
// Update endpoint to new version
await von.endpoints["ep_123"].patch({
version: "2025-01-15", // Now receives v2 payloads
});
Version Lifecycle
- Create new version when your payload schema changes
- New endpoints default to the latest version
- Existing endpoints continue receiving their subscribed version
- Customers migrate by updating their endpoint's version
- Deprecate old versions after all customers have migrated
Managing Versions
// List all versions
const { data: versions } = await von.versions.get();
// Get a specific version
const version = await von.versions["2025-01-15"].get();
// Update transforms
await von.versions["2025-01-15"].patch({
transforms: {
rename: { new_field: "old_field" },
},
});
// Delete a version (only if no endpoints use it)
await von.versions["2024-01-01"].delete();
Best Practices
Naming Conventions
Use date-based version IDs:
2025-01-152025-06-01
This makes it clear when versions were introduced and helps with ordering.
Migration Strategy
- Announce new version to customers
- Give migration window (30-90 days)
- Provide migration guides
- Monitor version usage in dashboard
- Deprecate old versions
Next Steps
- Sending Webhooks - Send versioned webhooks
- TypeScript SDK - Full SDK reference