Kobble
  1. Webhooks
Kobble
  • Introduction
  • API Fundamentals
    • Idempotency
    • Rate Limits
  • Authorization
    • Authorization
    • Get access token
      POST
  • Beneficiaries
    • List all beneficiaries
      GET
    • Get beneficiary by ID
      GET
    • Create beneficiary
      POST
    • Update beneficiary
      PUT
  • Cards
    • Cards API
    • Get all cards
      GET
    • Create a new card
      POST
    • Get card by ID
      GET
    • Update card status
      PATCH
    • Replace or renew card
      POST
    • Generate card secret
      POST
  • Card Programs
    • Card Programs API
    • Get all programs
      GET
    • Create a new program
      POST
    • Get program by ID
      GET
  • Clients
    • Clients API
    • Get all clients
    • Get client by ID
    • Create a new client
    • Update client status
  • Endusers
    • Endusers API
    • Get all endusers
    • Create a new enduser
    • Get enduser by ID
  • Transactions
    • Transactions API
    • Get all transactions
    • Create a transaction
    • Get transaction by ID
    • Create manual credit transaction
    • Create manual debit transaction
  • Wallets
    • Wallets API
    • Get all wallets
    • Create a new wallet
    • Get wallet by ID
    • Update wallet
  • Relays
    • Relays API
    • Create subscription
  • Webhooks
    • Webhooks API
    • Webhook Signature Verification
    • Get all webhooks
      GET
    • Create a webhook
      POST
    • Delete a webhook
      DELETE
  1. Webhooks

Webhooks API

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:
EnvironmentBase URL
Developmenthttps://dev.apikobble.net/
Staginghttps://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:
Refer to the Authorization Guide for steps on obtaining your token.

Endpoints#

Get all webhooks
Create a webhook
Delete a webhook

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" }
}
FieldDescription
idUnique webhook ID for idempotency.
entity_typetransaction, wallet, or tokenization.
entity_idID of the affected record.
typeEvent trigger (see table below).
client_idYour Kobble tenant ID.
created_atISO timestamp of event emission.
entityThe event data payload.

Event Types#

EntityTypeDescription
Transactiontransaction-createA new transaction is initiated.
transaction-updateA transaction is updated.
transaction-acceptTransaction was approved.
transaction-declineTransaction was declined.
Walletwallet-createWallet created.
wallet-updateWallet details or balance updated.
Tokenizationtokenization-otpOTP generated during provisioning.
tokenization-tnrToken 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
Example Payload:
{
  "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
Example Payload:
{
  "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#

Mapping behavior:
For transaction and wallet events:
client_id = resource owner
entity_id = resource id
No entity object is included
For tokenization events:
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.
Header Validation
Verify required headers are present (message ID and type)
Verify x-client-id header matches your client ID
2.
Signature Validation
Verify the request signature to ensure it came from Kobble
Download certificate from the provided certificate URL
Reject if signature is invalid
📖 See Webhook Signature Verification Guide for detailed implementation
3.
Client ID Validation
Verify client_id in the message matches your client ID
Verify it matches x-client-id header
Verify it matches client-id query parameter
Reject on any mismatch
4.
Idempotency Check
Extract id from parsed message
Check if id has been processed before
Skip processing if duplicate
5.
Response
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:
Steps:
1.
Start your local webhook endpoint server
2.
Expose it via ngrok
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#

Prerequisites:
iOS device with Apple Wallet support
Test card provisioned in Kobble
Webhook endpoint configured
Test Flow:
Verification Checklist:
tokenization-otp webhook received within 5 seconds
OTP is 6 digits
entity.wallet contains correct wallet information
entity.passcode_delivery_method_type is "sms" or appropriate value
entity.enduser_id matches the test user
tokenization-tnr webhook received after card addition
TNR entity.reason indicates successful activation

Testing Google Wallet Tokenization#

Prerequisites:
Android device with Google Pay installed
Test card provisioned in Kobble
Webhook endpoint configured
Test Flow:
Verification Checklist:
tokenization-otp webhook received within 5 seconds
OTP is 6 digits
entity.wallet contains correct wallet information
entity.passcode_delivery_method_type is "sms" or appropriate value
entity.enduser_id matches the test user
tokenization-tnr webhook received after card addition
TNR entity.reason indicates successful activation

3. Automated Testing with Mock Endpoints#

Create a test webhook endpoint that logs all received events:

4. Testing Transaction Events#

Test Scenarios:
1.
Create Transaction
Create a new transaction via API
Verify transaction-create webhook received
Verify entity_id matches transaction ID
2.
Update Transaction
Update transaction metadata
Verify transaction-update webhook received
3.
Accept Transaction
Simulate transaction approval
Verify transaction-accept webhook received
4.
Decline Transaction
Simulate transaction decline
Verify transaction-decline webhook received

5. Testing Wallet Events#

Test Scenarios:
1.
Create Wallet
Create a new wallet via API
Verify wallet-create webhook received
Verify entity_id matches wallet ID
2.
Update Wallet
Update wallet balance or metadata
Verify wallet-update webhook received

6. Testing Retry Behavior#

Test Retry Scenarios:
1.
Temporary Failure
Return 500 error for first request
Verify Kobble retries with exponential backoff
Return 200 on retry
Verify only one event processed (idempotency)
2.
Timeout
Simulate slow response (> 15 seconds)
Verify Kobble retries
Verify idempotency handling

7. Testing Tools and Resources#

Recommended Tools:
ngrok: Expose local endpoints (ngrok http 3000)
Postman: Test webhook endpoints manually
Webhook.site: Temporary webhook endpoint for testing
RequestBin: Alternative webhook testing service
Monitoring:
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#

CodeMeaning
200Successful request.
400Invalid request data.
401Unauthorized or missing token.
404Resource not found.
500Internal server error.

Error Response Format#

{
  "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#

Diagnosis:
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
Solution:
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#

Diagnosis:
Check if idempotency is implemented
Verify webhook id is being tracked
Solution:
Implement idempotency check using webhook id
Store processed webhook IDs in database
Return 200 OK even for duplicates

Issue: Signature validation failing#

Diagnosis:
Verify certificate download from the provided certificate URL
Check signature verification logic
Ensure all required fields are included
Solution:
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#

Diagnosis:
Verify webhook subscription is active
Check webhook endpoint logs
Verify tokenization flow was initiated correctly
Solution:
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

Performance#

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#

Kobble API Reference
Webhook Signature Verification Guide
Webhook Best Practices Guide
Modified at 2025-11-20 04:58:21
Previous
Create subscription
Next
Webhook Signature Verification
Built with