POST /webhook require an Authorization header:Authorization: Bearer <api_token>
{
"license_key": "XXXX-XXXX-XXXX", // omit to auto-generate
"product_code": "tiny_fontsize_yearly",
"status": "active", // default: active
"customer_id": "user@example.com",
"expires_at": 1780000000, // unix timestamp, null = never
"stripe_subscription_id": "sub_xxx",
"stripe_customer_id": "cus_xxx"
}
| HTTP | Body |
|---|---|
| 201 | {"success": true, "license_key": "..."} |
| 409 | {"error": "License key already exists"} |
| 401 | {"error": "Unauthorized"} |
{"license_key": "XXXX-XXXX-XXXX"}
| HTTP | Body |
|---|---|
| 200 | {
"license_key": "...",
"product_code": "...",
"status": "active",
"valid": true,
"expires_at": 1780000000,
"stripe_subscription_id": "sub_xxx",
"stripe_customer_id": "cus_xxx",
"stripe_price_id": "price_xxx",
"customer_id": "user@example.com"
}
|
| 404 | {"error": "License not found", "valid": false} |
| 400 | {"error": "license_key is required"} |
If an active license is past its expires_at, its status is automatically updated to expired on verify.
{
"product_code": "tiny_fontsize_yearly",
"status": "inactive",
"customer_id": "user@example.com",
"expires_at": 1780000000,
"stripe_subscription_id": "sub_xxx",
"stripe_customer_id": "cus_xxx",
"stripe_price_id": "price_xxx"
}
| HTTP | Body |
|---|---|
| 200 | {"success": true} |
| 404 | {"error": "License not found"} |
| 400 | {"error": "license_key required in URL"} |
| HTTP | Body |
|---|---|
| 200 | {"success": true} |
| 404 | {"error": "License not found"} |
Stripe-Signature
| Event | Action |
|---|---|
checkout.session.completed | Create or update license, set status active |
invoice.payment_succeeded | Renew license, extend expires_at, set active |
invoice.payment_failed | Set license status past_due |
customer.subscription.deleted | Set license status canceled |
customer.subscription.updated | Sync status and expires_at from Stripe |
All other event types are acknowledged and ignored. Webhook log: licensing/data/webhook.log
| Code | Name | Duration | Recurring |
|---|---|---|---|
tiny_fontsize_monthly |
Tiny FontSize | 30 days | yes |
tiny_fontsize_yearly |
Tiny FontSize | 365 days | yes |
tiny_fontsize_oneoff |
Tiny FontSize | — | no |
tiny_fontfamily_monthly |
Tiny FontFamily | 30 days | yes |
tiny_fontfamily_yearly |
Tiny FontFamily | 365 days | yes |
tiny_fontfamily_oneoff |
Tiny FontFamily | — | no |
tiny_fileimport_monthly |
Tiny FileImport | 30 days | yes |
tiny_fileimport_yearly |
Tiny FileImport | 365 days | yes |
tiny_fileimport_oneoff |
Tiny FileImport | — | no |
| Status | Meaning |
|---|---|
| active | License is valid and within its expiry window |
| inactive | Manually deactivated |
| expired | Past expires_at, set automatically on verify |
| canceled | Stripe subscription was canceled |
| past_due | Stripe invoice payment failed |