We are using cookies to improve your experience!

By clicking "Allow all", you agree to use of all cookies. Visit our Privacy Policy to learn more.

Webhooks Overview

Koteshen webhooks allow you to receive real-time notifications for key events in your invoicing workflow, such as invoice creation, updates, sending, payments, and overdue status changes. Webhooks are delivered as HTTP POST requests to a URL you specify, with a JSON payload containing event details.

Key Concepts

  • Events: Webhooks are triggered by specific events (e.g., invoice.created). You subscribe to events when creating a webhook endpoint.
  • Subscriptions: Manage webhook endpoints via the API to subscribe/unsubscribe from events and configure delivery URLs.
  • Security: Each webhook includes a secret for signature verification. Use the X-Koteshen-Signature header (HMAC SHA256 of the payload using your secret) to validate requests.
  • Retries: Failed deliveries (non-2xx responses) are retried up to 5 times with exponential backoff (1min, 5min, 15min, 1hr, 3hr).
  • Payload: All payloads include event (string), data (event-specific object), and occurred_at (ISO 8601 timestamp).
  • API Version: Webhooks use v1 payloads unless specified otherwise.

Supported Events

Event Name Description Triggered When
invoice.created A new invoice is created. Invoice saved for the first time.
invoice.updated An invoice is updated (e.g., items, status). Any field change, excluding payments.
invoice.sent An invoice is marked as sent/emailed. Status changes to “sent”.
invoice.paid An invoice receives a payment. New payment applied (full or partial).
invoice.overdue An invoice becomes overdue. Due date passes without full payment.

Event Payload Examples

invoice.created

{
  "event": "invoice.created",
  "data": {
    "id": 150,
    "number": "INV-8E5E-2268",
    "customer_id": 13,
    "currency": "USD",
    "total": { "cents": 43700, "currency_iso": "USD" },
    "status": "created",
    "issued_at": "2025-10-12T00:00:00.000Z",
    "due_at": "2025-10-12T00:00:00.000Z"
    // Full invoice object (see Show Invoice docs for structure)
  },
  "occurred_at": "2025-10-21T03:39:57.913Z"
}

invoice.updated

{
  "event": "invoice.updated",
  "data": {
    "id": 150,
    "number": "INV-8E5E-2268",
    // Changes only (diff from previous state)
    "status": "sent", // Example change
    "updated_at": "2025-10-21T04:00:00.000Z"
    // Full updated invoice object
  },
  "occurred_at": "2025-10-21T04:00:00.000Z"
}

invoice.sent

{
  "event": "invoice.sent",
  "data": {
    "id": 150,
    "number": "INV-8E5E-2268",
    "emailed_at": "2025-10-21T04:00:00.000Z"
    // Full invoice object
  },
  "occurred_at": "2025-10-21T04:00:00.000Z"
}

invoice.paid

{
  "event": "invoice.paid",
  "data": {
    "id": 150,
    "number": "INV-8E5E-2268",
    "balance": { "cents": 0, "currency_iso": "USD" }, // Updated balance
    "payments": [
      {
        "id": 37,
        "reference": "Payment 123",
        "amount": { "cents": 34000, "currency_iso": "USD" },
        "paid_at": "2025-10-12T00:00:00.000Z"
      }
    ]
    // Full invoice object
  },
  "occurred_at": "2025-10-21T04:41:11.901Z"
}

invoice.overdue

{
  "event": "invoice.overdue",
  "data": {
    "id": 150,
    "number": "INV-8E5E-2268",
    "due_at": "2025-10-12T00:00:00.000Z",
    "balance": { "cents": 43700, "currency_iso": "USD" }
    // Full invoice object
  },
  "occurred_at": "2025-10-21T10:00:00.000Z" // When overdue check runs
}

Managing Subscriptions

Use the endpoints below to create, view, update, and delete webhook subscriptions. Each subscription targets a specific URL and set of events.


POST /api/v1/webhook_endpoints

Create a new webhook endpoint subscription.

Path Parameters

None.

Request Body

Parameter Type Required Description
url string Yes The HTTPS URL to receive webhook deliveries. Must support POST and return 2xx on success.
enabled_events array Yes List of events to subscribe to (e.g., ["invoice.created", "invoice.paid"]). See supported events above.

Example Request

{
  "url": "https://your-app.com/webhooks/koteshen",
  "enabled_events": [
    "invoice.created",
    "invoice.updated",
    "invoice.sent",
    "invoice.paid",
    "invoice.overdue"
  ]
}

Response

Status Description
201 Created Subscription created successfully.

Response Body

{
  "data": {
    "id": 1,
    "url": "https://koteshen.com/api/v1/webhook_endpoints/1.json",
    "enabled_events": [
      "invoice.created",
      "invoice.updated",
      "invoice.sent",
      "invoice.paid",
      "invoice.overdue"
    ],
    "secret": "7410cb06136ce53dd5c5f7a270f5652743e1f17c",
    "api_version": "v1",
    "enabled": true,
    "created_at": "2025-10-17T23:56:10.396Z",
    "updated_at": "2025-10-18T05:12:54.125Z"
  }
}
  • secret: Use this to verify incoming webhook signatures. Keep it secure—it’s shown only once on creation.
  • enabled: Defaults to true. Set to false to pause deliveries without deleting.

Error Responses

Status Description Example Body
400 Bad Request Invalid URL or events. {"error": "Invalid event: 'invalid.event'"}
422 Unprocessable Entity Missing required fields. {"error": "URL is required"}

Usage Notes

  • Limit: Up to 10 active subscriptions per business.
  • HTTPS only: URLs must use HTTPS.
  • Verification: On creation, a test ping event may be sent to validate the URL.

GET /api/v1/webhook_endpoints

List all webhook endpoint subscriptions.

Path Parameters

None.

Query Parameters

Parameter Type Description Default
page integer Page number for pagination. 1
per_page integer Items per page (1-100). 10

Example Request

GET /api/v1/webhook_endpoints?page=1&per_page=5

Response

Status Description
200 OK List of subscriptions.

Response Body

{
  "data": [
    {
      "id": 1,
      "url": "https://your-app.com/webhooks/koteshen",
      "enabled_events": ["invoice.created", "invoice.paid"],
      "secret": "7410cb06136ce53dd5c5f7a270f5652743e1f17c", // Omitted for security in lists
      "api_version": "v1",
      "enabled": true,
      "created_at": "2025-10-17T23:56:10.396Z",
      "updated_at": "2025-10-18T05:12:54.125Z"
    }
  ],
  "meta": {
    "pagination": {
      "current_page": 1,
      "total_pages": 1,
      "total_count": 1
    }
  },
  "links": {
    "self": "https://koteshen.com/api/v1/webhook_endpoints?page=1",
    "first": "https://koteshen.com/api/v1/webhook_endpoints?page=1",
    "last": "https://koteshen.com/api/v1/webhook_endpoints?page=1"
  }
}

Error Responses

Status Description Example Body
401 Unauthorized Invalid token. {"error": "Unauthorized"}

GET /api/v1/webhook_endpoints/{id}

Retrieve a specific webhook endpoint subscription.

Path Parameters

Parameter Type Required Description
id integer Yes The subscription ID.

Example Request

GET /api/v1/webhook_endpoints/1

Response

Status Description
200 OK Subscription details.

Response Body

{
  "data": {
    "id": 1,
    "url": "https://your-app.com/webhooks/koteshen",
    "enabled_events": ["invoice.created", "invoice.paid"],
    "secret": "7410cb06136ce53dd5c5f7a270f5652743e1f17c",
    "api_version": "v1",
    "enabled": true,
    "created_at": "2025-10-17T23:56:10.396Z",
    "updated_at": "2025-10-18T05:12:54.125Z"
  }
}

Error Responses

Status Description Example Body
404 Not Found Subscription not found. {"error": "Not found"}

PATCH /api/v1/webhook_endpoints/{id}

Update an existing webhook endpoint subscription.

Path Parameters

Parameter Type Required Description
id integer Yes The subscription ID.

Request Body

Parameter Type Description
url string New delivery URL (optional).
enabled_events array Updated list of events (optional).
enabled boolean Enable/disable deliveries (optional).

Example Request

{
  "enabled_events": ["invoice.created", "invoice.overdue"],
  "enabled": true
}

Response

Status Description
200 OK Updated subscription.

Response Body Same as GET /api/v1/webhook_endpoints/{id}.

Error Responses

Status Description Example Body
400 Bad Request Invalid events. {"error": "Invalid event"}
404 Not Found Subscription not found. {"error": "Not found"}

DELETE /api/v1/webhook_endpoints/{id}

Delete a webhook endpoint subscription.

Path Parameters

Parameter Type Required Description
id integer Yes The subscription ID.

Example Request

DELETE /api/v1/webhook_endpoints/1

Response

Status Description
204 No Content Subscription deleted. No body returned.

Error Responses

Status Description Example Body
404 Not Found Subscription not found. {"error": "Not found"}

Usage Notes

  • Deleting a subscription stops all deliveries immediately.
  • No undo—use PATCH to disable instead if needed.

Integration Tips

  1. Verification Code: Compute HMAC-SHA256(payload, secret) and compare to X-Koteshen-Signature header.
  2. Idempotency: Use occurred_at and event IDs to deduplicate.
  3. Testing: Use tools like webhook.site for initial setup. Trigger test events via API (e.g., create an invoice).
  4. Rate Limits: Webhooks are rate-limited per subscription (1000/min).
  5. Support: For issues, contact support@koteshen.com with subscription ID and event samples.

For full API reference, see Invoices, Customers, etc.