Skip to main content

Webhooks Overview

Webhooks let you receive real-time notifications when events happen on your WorkFunder account. Instead of polling the API to check task status, WorkFunder sends an HTTP POST request to your server whenever a task is funded, a worker submits proof, a task is completed, and more.

How Webhooks Work

  1. An event occurs on your account (e.g., a worker submits proof)
  2. WorkFunder sends an HTTP POST request to your configured webhook URL
  3. Your server processes the event and returns a 2xx response
  4. If delivery fails, WorkFunder retries with exponential backoff
WorkFunder Platform

│ task.proof_submitted event


HTTP POST to https://your-server.com/webhooks/workfunder

│ Headers:
│ Content-Type: application/json
│ X-WorkFunder-Signature: v1=abc123...
│ X-WorkFunder-Timestamp: 1708790400

│ Body:
│ { "event": "task.proof_submitted", "data": { ... } }


Your Server
→ Verify signature
→ Process event
→ Return 200 OK

Setting Up a Webhook Endpoint

1. Create an Endpoint

Build an HTTP endpoint on your server that:

  • Accepts POST requests
  • Returns a 2xx status code within 30 seconds
  • Verifies the webhook signature (see Webhook Security)
// Example: Express.js webhook handler
import express from "express";
import crypto from "crypto";

const app = express();
app.use(express.json());

app.post("/webhooks/workfunder", (req, res) => {
// 1. Verify the signature (see Security docs)
const signature = req.headers["x-workfunder-signature"];
const timestamp = req.headers["x-workfunder-timestamp"];

if (!verifySignature(req.body, signature, timestamp)) {
return res.status(401).send("Invalid signature");
}

// 2. Process the event
const { event, data } = req.body;

switch (event) {
case "task.completed":
console.log(`Task ${data.id} completed!`);
// Fetch proofs, update your database, etc.
break;

case "task.proof_submitted":
console.log(`Proof submitted for task ${data.id}`);
break;

case "task.cancelled":
console.log(`Task ${data.id} was cancelled`);
break;

default:
console.log(`Unhandled event: ${event}`);
}

// 3. Return 200 to acknowledge receipt
res.status(200).json({ received: true });
});

app.listen(3000);

2. Configure Your Webhook URL

Set your webhook URL and select which events to receive. You can do this from the Dashboard or via the API:

curl -X PUT https://api.workfunder.com/v1/account/webhook \
-H "Authorization: Bearer wf_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/workfunder",
"events": [
"task.created",
"task.funded",
"task.assigned",
"task.proof_submitted",
"task.completed",
"task.cancelled",
"task.disputed"
]
}'

3. Test Your Endpoint

Send a test event to verify your endpoint is working:

curl -X POST https://api.workfunder.com/v1/account/webhook/test \
-H "Authorization: Bearer wf_live_your_key"
info

The test endpoint sends a sample task.created event to your configured webhook URL to verify it's reachable and responding correctly.

Webhook URL Requirements

  • Must use HTTPS (HTTP is not accepted)
  • Must respond within 30 seconds
  • Must return a 2xx status code to acknowledge receipt
  • Should be publicly accessible (not behind a firewall without allowlisting)

Event Subscriptions

You can subscribe to all events or select specific ones. If no events are specified, all events are delivered.

Available events are organized by resource:

ResourceEvents
Tasktask.created, task.funded, task.posted, task.assigned, task.started, task.proof_submitted, task.completed, task.proof_rejected, task.cancelled, task.expired, task.disputed, task.refunded
Workerworker.verified

See the Events page for the full payload format of each event.

One Endpoint Per Account

In the current version, each developer account supports one webhook endpoint URL. All subscribed events are delivered to this single URL.

tip

If you need to route events to different services, use a single webhook receiver that inspects the event type and forwards to the appropriate internal service.

Delivery Guarantees

  • At-least-once delivery: Events may be delivered more than once. Your handler should be idempotent.
  • Ordering: Events are generally delivered in order, but this is not guaranteed. Use timestamps and task status to handle out-of-order events.
  • Retries: Failed deliveries are retried up to 3 times with exponential backoff. See Webhook Security for details.

Next Steps