Webhooks
Reference for AI provider callbacks and payment webhooks used by Kensa.
Webhooks
Kensa uses webhooks for two purposes: receiving completion notifications from AI video providers, and processing payment events from Creem/Stripe.
AI Provider Callbacks
When an AI provider finishes generating a video (or encounters an error), it sends a callback to Kensa's webhook endpoint.
Endpoint
POST /api/v1/video/callback/{provider}
Where {provider} is one of: evolink, kie.
Authentication
Callbacks are authenticated using the AI_CALLBACK_SECRET environment variable. The provider includes this secret in the request to verify authenticity.
Callback Flow
- Kensa sends a video generation request to the AI provider.
- The provider processes the request asynchronously.
- On completion (or failure), the provider sends a POST request to the callback URL.
- Kensa validates the callback secret.
- On success:
- The video file is downloaded from the provider.
- The video is uploaded to R2/S3 storage.
- Credits are settled (consumed).
- The video status is updated to
COMPLETED.
- On failure:
- Credits are released (returned to user).
- The video status is updated to
FAILED. - The error message is recorded.
Callback Payload (Evolink Example)
{
"taskId": "ext_task_abc123",
"status": "completed",
"videoUrl": "https://provider-cdn.example.com/output.mp4",
"duration": 10,
"resolution": "720p"
}
Callback Payload (Failure)
{
"taskId": "ext_task_abc123",
"status": "failed",
"error": "Content policy violation"
}
Environment Variables
# The URL that AI providers call back to after generation
AI_CALLBACK_URL=https://your-domain.com/api/v1/video/callback
# Secret for verifying callback authenticity
AI_CALLBACK_SECRET=your-secret-here
Payment Webhooks
Creem Webhooks
Creem sends payment events to Kensa to handle subscription management and credit allocation.
Endpoint
POST /api/auth/creem/webhook
This endpoint is managed by the Better Auth Creem plugin and handles webhook verification automatically using the CREEM_WEBHOOK_SECRET.
Supported Events
| Event | Description | Action |
|---|---|---|
checkout.completed | One-time payment completed | Add credits to user account |
subscription.created | New subscription started | Create subscription record, add credits |
subscription.updated | Subscription plan changed | Update subscription record |
subscription.cancelled | Subscription cancelled | Mark subscription as cancelled |
subscription.expired | Subscription period ended | Update subscription status |
Automatic Credit Allocation
When a checkout.completed or subscription.created event is received:
- The webhook handler verifies the signature using
CREEM_WEBHOOK_SECRET. - The user is identified from the payment metadata.
- Credits are added to the user's account as a new credit package.
- A credit transaction record is created for audit purposes.
Environment Variables
CREEM_API_KEY='creem_live_xxx'
CREEM_WEBHOOK_SECRET='whsec_xxx'
Stripe Webhooks (Secondary)
Stripe webhooks are available as a secondary payment option.
Endpoint
POST /api/webhooks/stripe
Supported Events
| Event | Description |
|---|---|
checkout.session.completed | Payment session completed |
customer.subscription.created | Subscription created |
customer.subscription.updated | Subscription updated |
customer.subscription.deleted | Subscription cancelled |
invoice.payment_succeeded | Recurring payment succeeded |
invoice.payment_failed | Recurring payment failed |
Environment Variables
STRIPE_API_KEY='sk_live_xxx'
STRIPE_WEBHOOK_SECRET='whsec_xxx'
Webhook Security
Signature Verification
All webhooks verify the request signature to ensure authenticity:
- AI Callbacks: Verified using
AI_CALLBACK_SECRET. - Creem: Verified using
CREEM_WEBHOOK_SECRET(handled by Better Auth plugin). - Stripe: Verified using
STRIPE_WEBHOOK_SECRET(handled by Stripe SDK).
Best Practices
- Always use HTTPS in production for webhook endpoints.
- Never expose secrets in client-side code or logs.
- Handle idempotency: Webhooks may be delivered more than once. Use transaction IDs to avoid duplicate processing.
- Return 200 quickly: Process webhook payloads asynchronously if needed. Return a 200 status code promptly to avoid retries.
- Monitor failures: Set up alerts for failed webhook deliveries in your payment provider dashboard.
Testing Webhooks Locally
During development, your local server is not accessible from the internet. Use a tunneling service to receive webhooks:
# Using ngrok
ngrok http 3000
Then update your webhook URLs in the Creem/Stripe dashboards to point to the ngrok URL:
https://abc123.ngrok.io/api/auth/creem/webhook
https://abc123.ngrok.io/api/webhooks/stripe
For AI provider callbacks, update AI_CALLBACK_URL in .env.local:
AI_CALLBACK_URL=https://abc123.ngrok.io/api/v1/video/callback