Kwill

Testing locally

How to receive Kwill webhook events on your local development machine.

Kwill can only deliver events to publicly reachable HTTPS URLs. To test webhooks locally, you need a tunnel that forwards traffic from a public URL to your local server.


Step 1 — Start your local server

Start your webhook handler on a local port. For example, with Express on port 3000:

node server.js
# Listening on http://localhost:3000

Step 2 — Open a tunnel

ngrok is the most widely used option and has a free tier that works for local testing.

# Install ngrok (first time only)
brew install ngrok            # macOS
# or download from https://ngrok.com/download

# Start the tunnel
ngrok http 3000

ngrok prints a public URL like https://a1b2c3d4.ngrok-free.app. Copy it.

Alternatives

ToolInstallCommand
Cloudflare Tunnelbrew install cloudflaredcloudflared tunnel --url http://localhost:3000
localtunnelnpm i -g localtunnellt --port 3000

Step 3 — Register a webhook endpoint

Use the public URL from your tunnel as the webhook URL. Append your handler path:

curl -X POST https://usekwill.com/api/v1/webhooks \
  -H "Authorization: Bearer $KWILL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://a1b2c3d4.ngrok-free.app/webhooks/kwill",
    "event_types": ["invoice.paid", "proposal.signed"]
  }'

The response includes your id and the secret (shown once — save it as KWILL_WEBHOOK_SECRET).


Step 4 — Send a test event

From the dashboard: open the webhook endpoint, click Send test event.

Or via the API:

curl -X POST https://usekwill.com/api/v1/webhooks/{id}/test \
  -H "Authorization: Bearer $KWILL_API_KEY"

Check your local server logs — you should see the webhook.test payload arrive. Verify that your signature check passes.


Step 5 — Trigger real events

Perform an action in Kwill that fires one of your subscribed events. For example, pay a test invoice in the dashboard to trigger invoice.paid.

Watch the ngrok web UI at http://localhost:4040 to inspect the full request and response in real time.


Cleanup

Delete the local webhook endpoint when you're done:

curl -X DELETE https://usekwill.com/api/v1/webhooks/{id} \
  -H "Authorization: Bearer $KWILL_API_KEY"

Webhook deletions are allowed even on frozen workspaces.

On this page