Skip to main content

Overview

Webhooks allow your application to receive real-time HTTP notifications when events occur in FieldWise. Instead of polling the API, webhooks push data to your endpoint instantly.

Supported Events

EventDescription
document.processing.startedDocument processing has begun
document.processing.completedDocument processed successfully
document.processing.failedDocument processing failed

Webhook Payload

{
  "event": "document.processing.completed",
  "timestamp": "2026-01-16T10:09:57.792Z",
  "data": {
    "task_identifier": "DocumentExtraction:a29f03e7-5a95-49a6-a845-ef90b15d0b31",
    "document_id": 164,
    "external_id": null,
    "status": "completed",
    "message": "Document processing completed",
    "file_name": "invoice.pdf"
  }
}

Payload Fields

FieldTypeDescription
eventstringEvent type (dot-notation)
timestampstringISO 8601 timestamp
data.task_identifierstringUnique task ID for tracking
data.document_idinteger | nullDocument ID (available on completion)
data.external_idstring | nullYour custom reference ID
data.statusstringprocessing, completed, or failed
data.messagestringHuman-readable status description
data.file_namestringOriginal file name

Security Headers

Every webhook includes these headers:
HeaderDescription
X-FieldWise-SignatureHMAC-SHA256 signature
X-FieldWise-TimestampTimestamp used in signature
X-FieldWise-EventEvent type

Signature Verification

Always verify webhook signatures to ensure requests come from FieldWise.
const crypto = require('crypto');

function verifyWebhook(rawBody, signature, timestamp, secret) {
  // 1. Check timestamp is recent (5 min)
  const age = Math.abs(Date.now() - new Date(timestamp).getTime()) / 1000;
  if (age > 300) return false;
  
  // 2. Compute expected signature
  const message = `${timestamp}.${rawBody}`;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');
  
  // 3. Compare (constant-time)
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express.js example
app.post('/webhooks', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-fieldwise-signature'];
  const timestamp = req.headers['x-fieldwise-timestamp'];
  
  if (!verifyWebhook(req.body.toString(), signature, timestamp, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(req.body);
  console.log('Received:', event.event, event.data.status);
  
  res.status(200).send('OK');
});

Retry Policy

Failed deliveries are automatically retried:
AttemptDelay
1st retry30 seconds
2nd retry60 seconds
3rd retry120 seconds
After 3 failed attempts, the webhook is marked as failed.

Best Practices

Respond Quickly

Return 200 OK immediately, then process asynchronously. Timeout is 30 seconds.

Handle Duplicates

Use task_identifier to deduplicate. Webhooks may be delivered more than once.

Use HTTPS

Always use HTTPS endpoints in production to protect webhook payloads.

Verify Signatures

Always verify the X-FieldWise-Signature header before processing.

Managing Webhooks

Configure webhooks directly in the FieldWise dashboard under Settings → Webhooks. From there you can:
  • Create new webhooks
  • Edit webhook settings
  • Delete webhooks
  • Send test payloads
  • Rotate secrets