Kobble Webhooks API#
Introduction#
The Kobble Webhooks API allows your application to receive real-time event notifications from the Kobble platform. You can create, view, and delete webhook subscriptions, and securely handle webhook events.
Overview#
Subscribe to Kobble event notifications such as transactions, wallets, and tokenization.
Manage subscriptions using RESTful endpoints.
Validate inbound webhook requests securely.
Receive JSON payloads with consistent, typed event structures.
Key Features#
RESTful API with clear, resource-based endpoints.
Secure authentication using bearer tokens.
Idempotent webhook delivery with retry handling.
Support for local, staging, and production environments.
Base URLs#
Use the appropriate base URL depending on your environment:| Environment | Base URL |
|---|
| Development | https://dev.apikobble.net/ |
| Staging | https://staging.apikobble.net/ |
Ensure all endpoint paths are prefixed with the correct base URL for your environment.
Authentication#
All API requests require an access token. Include it in the request headers:
Endpoints#
Architecture Overview#
The Kobble webhook system provides reliable, scalable event distribution with automatic retries. When you create a webhook subscription, Kobble will deliver events to your endpoint as they occur.
Webhook Subscription Flow#
Sequence Diagram: Initial Setup#
Detailed Steps#
When you first create a webhook subscription, Kobble will send a subscription confirmation request to your webhook endpoint. This handshake must be completed before you start receiving live events.Steps#
1.
Receive the confirmation request
Your webhook endpoint will receive a JSON payload containing a field named SubscribeURL.
2.
Confirm the subscription
Make an HTTP GET request to the SubscribeURL and return a 200 OK response.
3.
Start receiving events
Once confirmed, Kobble will send notification messages containing the event data to your endpoint.
4.
Handle retries
If your endpoint doesn't respond with 2xx, Kobble will automatically retry with exponential backoff.
Example Flow#
POST /webhooks/kobble
→ Kobble sends Subscription Confirmation
→ You GET SubscribeURL to confirm
→ Kobble sends Notification (actual event)
→ You return 200 OK
Webhook Event Delivery Flow#
Sequence Diagram: Event Processing#
Webhook Events#
Webhook events are lean notifications indicating that an event occurred - not carrying the full entity data. Use the entity_id and entity_type to fetch full details from the Kobble API.The webhook acts as an event trigger, while the API remains the source of truth.General Event Structure#
{
"id": "d2e89f3f-48bd-4bfc-8fd0-2d6b8e7207c1",
"entity_type": "transaction",
"entity_id": "b3fd2bd3-64b3-45ce-af2b-9fd4c8d0d2f1",
"type": "transaction-create",
"client_id": "1f9a3f9c-0d2d-4dac-8c46-8b8b0d7f2bf5",
"created_at": "2024-09-18T11:47:03.123Z",
"entity": { "...": "context-specific data" }
}
| Field | Description |
|---|
id | Unique webhook ID for idempotency. |
entity_type | transaction, wallet, or tokenization. |
entity_id | ID of the affected record. |
type | Event trigger (see table below). |
client_id | Your Kobble tenant ID. |
created_at | ISO timestamp of event emission. |
entity | The event data payload. |
Event Types#
| Entity | Type | Description |
|---|
| Transaction | transaction-create | A new transaction is initiated. |
| transaction-update | A transaction is updated. |
| transaction-accept | Transaction was approved. |
| transaction-decline | Transaction was declined. |
| Wallet | wallet-create | Wallet created. |
| wallet-update | Wallet details or balance updated. |
| Tokenization | tokenization-otp | OTP generated during provisioning. |
| tokenization-tnr | Token activation event. |
Tokenization Flow: Adding Cards to Digital Wallets#
Swimlane Diagram: Apple Wallet & Google Wallet Tokenization#
Tokenization Event Details#
tokenization-otp Event#
This event is fired when an OTP is generated during the card provisioning process. Your application should:1.
Receive the webhook notification
2.
Extract the OTP from entity.otp
3.
Deliver the OTP to the end user via SMS or in-app notification
4.
The user will need this OTP to complete the wallet addition
{
"id": "b57f27d4-7a2d-4c6b-8b5d-0e5a4f9e7c2a",
"created_at": "2025-10-28T10:29:00.000Z",
"client_id": "b0d2c7a9-9a1e-4e23-8e07-8a1ad1ad1e12",
"entity_id": "2f6ac9b4-8b8f-4f6a-9f1c-4f7b9c6a0e1b",
"entity_type": "tokenization",
"type": "tokenization-otp",
"entity": {
"wallet": {"id": "780ae956-a932-4c1e-9c4e-41e5d723d599", "label": "Primary Wallet"},
"otp": "936251",
"enduser_id": "e6d1b2c3-4f5a-6789-0abc-def123456789",
"passcode_delivery_method_type": "sms"
}
}
tokenization-tnr Event#
This event is fired when a token is activated or deactivated. Common reasons include:Token successfully activated
User removed card from wallet
Token suspended by payment network
User requested tokenization stop
{
"id": "a61d4a38-27a4-4b55-b871-32a6b0e2b5f0",
"created_at": "2025-10-28T10:29:00.000Z",
"client_id": "b0d2c7a9-9a1e-4e23-8e07-8a1ad1ad1e12",
"entity_id": "5e7a3d1c-6f4b-4d2e-8a9c-1b2f3c4d5e6f",
"entity_type": "tokenization",
"type": "tokenization-tnr",
"entity": {
"reason": "User requested to stop tokenization",
"enduser_id": "e6d1b2c3-4f5a-6789-0abc-def123456789"
}
}
Detailed Event Examples and Field Mappings#
For transaction and wallet events:client_id = resource owner
No entity object is included
client_id = respective enduser's owner
entity_id = new UUID (synthetic id for the notification)
entity is populated with extra details depending on the event type
Transaction Events#
transaction-create#
{
"id": "c0a80a2d-0f4a-4d1f-8c1d-a9f0b8c6d2e1",
"created_at": "2025-10-28T10:29:00.000Z",
"client_id": "c9a0c6d8-7fcb-4e32-9a35-2b2b4fdbf3d1",
"entity_id": "2a7bffcf-1a73-4d0d-9f80-7a3f8d3a56b2",
"entity_type": "transaction",
"type": "transaction-create"
}
transaction-update#
{
"id": "5f43d9f4-6e9c-4cde-95d8-0f9f4b0a2c13",
"created_at": "2025-10-28T10:29:00.000Z",
"client_id": "c9a0c6d8-7fcb-4e32-9a35-2b2b4fdbf3d1",
"entity_id": "2a7bffcf-1a73-4d0d-9f80-7a3f8d3a56b2",
"entity_type": "transaction",
"type": "transaction-update"
}
transaction-accept#
{
"id": "48a214e3-451c-42ec-a774-88246291a8f5",
"created_at": "2025-10-28T03:40:10.328Z",
"client_id": "67c97c3b-e41a-44e5-8a16-ea5c471ba21e",
"entity_id": "58c5ce5b-95c1-4175-aff5-47cf2f7266bb",
"entity_type": "transaction",
"type": "transaction-accept"
}
transaction-decline#
{
"id": "f0b6a9a4-4c01-4c86-9e59-8f2e7fc1c0a2",
"created_at": "2025-10-28T10:29:00.000Z",
"client_id": "c9a0c6d8-7fcb-4e32-9a35-2b2b4fdbf3d1",
"entity_id": "2a7bffcf-1a73-4d0d-9f80-7a3f8d3a56b2",
"entity_type": "transaction",
"type": "transaction-decline"
}
Wallet Events#
wallet-create#
{
"id": "31265e3c-a88a-4baf-9d32-1e7c5c0ea029",
"created_at": "2025-10-28T00:39:30.926Z",
"client_id": "e95e4ac7-315c-40e2-9e2e-3f143eb533c4",
"entity_id": "35d85b8b-b3ae-4421-b654-eacd65ad2c9e",
"entity_type": "wallet",
"type": "wallet-create"
}
wallet-update#
{
"id": "57508716-73ec-4a34-a10b-ac6ad3305440",
"created_at": "2025-10-28T03:40:10.215Z",
"client_id": "a47cfade-637c-4099-befe-f9f2b5a616ed",
"entity_id": "f5126496-4079-4f89-8cba-dc3ae518b810",
"entity_type": "wallet",
"type": "wallet-update"
}
Webhook Request Validation Flow#
Flowchart: Security Validation#
Validation Checklist#
For every webhook request, perform these checks:1.
Verify required headers are present (message ID and type)
Verify x-client-id header matches your client ID
2.
Verify the request signature to ensure it came from Kobble
Download certificate from the provided certificate URL
Reject if signature is invalid
3.
Verify client_id in the message matches your client ID
Verify it matches x-client-id header
Verify it matches client-id query parameter
4.
Extract id from parsed message
Check if id has been processed before
Skip processing if duplicate
5.
Always return 200 OK for valid requests (even duplicates)
Return error codes only for validation failures
Respond quickly (< 5 seconds) to prevent retries
Testing Webhook Events#
Testing Strategy Overview#
Testing webhooks requires simulating real-world scenarios. Below are strategies for testing different event types, with special focus on tokenization events for Apple Wallet and Google Wallet.1. Local Testing with Webhook Proxies#
Use tools like ngrok or localtunnel to expose your local endpoint:1.
Start your local webhook endpoint server
3.
Create a webhook subscription using the ngrok URL
4.
Trigger events in your Kobble environment
5.
Monitor webhook deliveries in real-time
2. Testing Tokenization Events#
Testing Apple Wallet Tokenization#
iOS device with Apple Wallet support
Test card provisioned in Kobble
Webhook endpoint configured
Testing Google Wallet Tokenization#
Android device with Google Pay installed
Test card provisioned in Kobble
Webhook endpoint configured
3. Automated Testing with Mock Endpoints#
Create a test webhook endpoint that logs all received events:4. Testing Transaction Events#
1.
Create a new transaction via API
Verify transaction-create webhook received
Verify entity_id matches transaction ID
2.
Update transaction metadata
Verify transaction-update webhook received
3.
Simulate transaction approval
Verify transaction-accept webhook received
4.
Simulate transaction decline
Verify transaction-decline webhook received
5. Testing Wallet Events#
1.
Create a new wallet via API
Verify wallet-create webhook received
Verify entity_id matches wallet ID
2.
Update wallet balance or metadata
Verify wallet-update webhook received
6. Testing Retry Behavior#
1.
Return 500 error for first request
Verify Kobble retries with exponential backoff
Verify only one event processed (idempotency)
2.
Simulate slow response (> 15 seconds)
Verify idempotency handling
ngrok: Expose local endpoints (ngrok http 3000)
Postman: Test webhook endpoints manually
Webhook.site: Temporary webhook endpoint for testing
RequestBin: Alternative webhook testing service
Log all webhook requests with timestamps
Track webhook IDs for idempotency verification
Monitor response times (should be < 5 seconds)
Alert on repeated failures
Error Handling#
| Code | Meaning |
|---|
200 | Successful request. |
400 | Invalid request data. |
401 | Unauthorized or missing token. |
404 | Resource not found. |
500 | Internal server error. |
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
}
}
Retry Behavior#
Kobble automatically retries failed webhook deliveries:Retry Schedule: Exponential backoff
Retry Triggers: Non-2xx responses, timeouts, connection errors
Best Practice: Always return 200 OK quickly, process asynchronously
Troubleshooting#
Common Issues#
Issue: Webhooks not being received#
1.
Check subscription status in Kobble API
2.
Verify endpoint is publicly accessible
3.
Verify subscription confirmation was completed
4.
Check webhook endpoint logs for incoming requests
Ensure endpoint returns 200 OK for subscription confirmation
Check firewall/security group rules
Verify HTTPS certificate is valid
Verify endpoint URL matches the registered subscription
Issue: Duplicate webhook deliveries#
Check if idempotency is implemented
Verify webhook id is being tracked
Implement idempotency check using webhook id
Store processed webhook IDs in database
Return 200 OK even for duplicates
Issue: Signature validation failing#
Verify certificate download from the provided certificate URL
Check signature verification logic
Ensure all required fields are included
Use standard signature verification utilities
Verify certificate URL is from a trusted domain
Check that message hasn't been modified
Ensure you're validating all required headers and body fields
Issue: Tokenization OTP not received#
Verify webhook subscription is active
Check webhook endpoint logs
Verify tokenization flow was initiated correctly
Test webhook endpoint with other event types
Verify your client_id matches the subscription
Check that the tokenization request was successful
Best Practices#
Security#
1.
Always validate signatures - Never trust unverified requests
2.
Verify client_id - Check header, query param, and message content
3.
Use HTTPS - Never accept webhooks over HTTP
4.
Implement rate limiting - Protect against abuse
5.
Log all requests - For debugging and security auditing
1.
Respond quickly - Return 200 OK within 5 seconds
2.
Process asynchronously - Don't block webhook handler with heavy work
3.
Implement idempotency - Handle duplicate deliveries gracefully
4.
Monitor response times - Alert on slow endpoints
Reliability#
1.
Handle all message types - SubscriptionConfirmation, Notification, UnsubscribeConfirmation
2.
Implement retry logic - For downstream dependencies
3.
Use idempotent operations - Safe to retry processing
4.
Monitor webhook health - Track success/failure rates
Notes#
Webhook payloads are lean - use APIs for full entity details.
Always respond promptly with 2xx.
Use HTTPS with valid SSL certificates.
Handle retries gracefully and idempotently.
Store webhook IDs for idempotency and debugging.
Test webhook endpoints thoroughly before production use.
Additional Resources#
Modified at 2025-11-20 04:58:21