Field NationDeveloper Platform
Field NationDeveloper Platform
IntroductionQuickstartAPI Playground

Documentation

Creating WebhooksSecurity Best Practices

Implementation

Handling EventsMonitoring WebhooksTesting Webhooks

Advanced

Payload Customization

Support

Migration Guide
Guides

Creating Webhooks

Step-by-step guide to creating and configuring webhooks using the Web UI or REST API with examples for both methods.


Prerequisites

Before creating a webhook, ensure you have:

  • ✅ Field Nation API credentials (client_id and client_secret)
  • ✅ OAuth access token (for API method)
  • ✅ HTTPS endpoint URL ready to receive webhooks
  • ✅ List of events you want to subscribe to

Review prerequisites →


Method 1: Web UI (Visual)

Best for:

  • Quick setup and testing
  • Non-technical users
  • Visual configuration
  • One-off webhook creation

Navigate to Webhooks Dashboard

Sandbox: https://ui-sandbox.fndev.net/integrations/webhooks

Production: https://app.fieldnation.com/integrations/webhooks

Click "Create New"

Located in the top-right corner of the dashboard.

Configure Basic Settings

Fill in the required fields:

Webhook URL:

  • Enter your HTTPS endpoint (e.g., https://your-endpoint.com/webhooks)
  • Must be publicly accessible
  • Must use HTTPS (HTTP not allowed)

HTTP Method:

  • POST (recommended) - Standard for webhooks
  • PUT - Use if your endpoint requires PUT

Status:

  • Active - Start receiving events immediately
  • Inactive - Create paused, activate later

Select Events

Choose which events trigger this webhook:

Option 1: Select All Events

  • Check "Subscribe to all events"
  • Receives all 33 events automatically
  • Future events included automatically

Option 2: Select Specific Events

  • Click "Add Event"
  • Search or browse available events
  • Select only events your system processes

Recommendation: Start with a small set of events (4-6), then expand as needed. Subscribing to unused events creates unnecessary processing overhead.

Configure Advanced Settings (Optional)

Click "Advanced Settings" to configure:

Notification Email:

  • Email address for delivery failure alerts
  • Recommended: Use a monitored team email

Custom Headers:

  • Add authentication tokens or custom identifiers
  • Click "Add Header"
  • Enter key-value pairs

Example:

Authorization: Bearer your-api-token
X-Custom-ID: integration-prod
X-Environment: production

Reserved Prefix: Headers cannot start with x-fn- (reserved for Field Nation).

Secret Key:

  • Auto-generated by default
  • Optionally provide your own UUID
  • Used for HMAC-SHA256 signature verification

Review & Create

  • Review all settings
  • Click "Create Webhook"
  • Save the webhook ID and secret - you'll need these

UI Configuration Example

Webhook Creation Form

Advanced Settings:

Advanced Webhook Configuration

After Creation: The webhook is immediately active if status was set to "active". Test by triggering an event!


Method 2: REST API (Programmatic)

Best for:

  • Automation and infrastructure-as-code
  • Multiple webhook creation
  • CI/CD pipelines
  • Dynamic configuration

Step 1: Get OAuth Access Token

Generate Access Token
curl -X POST https://api-sandbox.fndev.net/authentication/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Step 2: Create Webhook

Create Webhook
curl -X POST https://api-sandbox.fndev.net/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-endpoint.com/webhooks",
    "method": "post",
    "status": "active",
    "events": [
      "workorder.created",
      "workorder.status.published",
      "workorder.status.assigned",
      "workorder.status.work_done",
      "workorder.status.approved"
    ],
    "notificationEmail": "webhook-alerts@example.com"
  }'

Response:

{
  "metadata": {
    "timestamp": "2025-01-15T10:30:00Z"
  },
  "result": {
    "id": 123,
    "webhookId": "wh_abc123def456",
    "companyId": 789,
    "userId": 456,
    "url": "https://your-endpoint.com/webhooks",
    "method": "post",
    "status": "active",
    "secret": "01999f51-5c66-4449-b441-6b4a053fee6a",
    "events": [
      "workorder.created",
      "workorder.status.published",
      "workorder.status.assigned",
      "workorder.status.work_done",
      "workorder.status.approved"
    ],
    "notificationEmail": "webhook-alerts@example.com",
    "modelProperties": [],
    "isIntegrationOnly": false,
    "createdAt": "2025-01-15T10:30:00Z",
    "updatedAt": "2025-01-15T10:30:00Z"
  }
}

Save the secret! The secret field is only returned during creation. Store it securely—you'll need it for signature verification.

Step 3: Verify Webhook Created

Get Webhook Details
curl -X GET https://api-sandbox.fndev.net/api/v1/webhooks/wh_abc123def456 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Request Body Reference

Required Fields

Prop

Type

Description

urlstring

HTTPS endpoint URL where webhook notifications will be sent. Must be publicly accessible and use HTTPS.

methodstring (enum)

HTTP method for delivery. Values: `post` (recommended) or `put`.

statusstring (enum)

Initial webhook status. Values: `active`, `inactive`, `archived`.

eventsarray<string>

Array of event names to subscribe to. Must contain at least 1 event. See [event catalog](/docs/webhooks/concepts/events) for complete list.

Optional Fields

Prop

Type

Description

secret?string (UUID)

Custom secret for HMAC-SHA256 signing. Auto-generated if omitted. Must be valid UUID format.

notificationEmail?string (email)

Email address to receive delivery failure notifications and alerts.

isIntegrationOnly?boolean

Whether webhook is restricted to API-only access. Default: false.

webhookAttribute?object

Custom headers and legacy field mappings.

webhookScript?object

Payload customization configuration. Contains `scriptLanguage` (jsonata or json), `script` (transformation script), and `enabled` (boolean toggle). See [Payload Customization Guide](/docs/webhooks/guides/payload-customization).


Configuration Examples

Minimal Configuration

Subscribe to single event:

{
  "url": "https://your-endpoint.com/webhooks",
  "method": "post",
  "status": "active",
  "events": ["workorder.status.published"]
}

Production-Ready Configuration

Full configuration with custom headers and notifications:

{
  "url": "https://api.example.com/integrations/fieldnation/webhooks",
  "method": "post",
  "status": "active",
  "events": [
    "workorder.created",
    "workorder.status.published",
    "workorder.status.assigned",
    "workorder.status.checked_in",
    "workorder.status.work_done",
    "workorder.status.approved",
    "workorder.status.paid"
  ],
  "secret": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "notificationEmail": "integrations-alerts@example.com",
  "webhookAttribute": {
    "header": {
      "Authorization": "Bearer prod-api-token-xyz",
      "X-Webhook-Environment": "production",
      "X-Webhook-Version": "v1",
      "X-Team-Owner": "integrations"
    }
  }
}

Multi-Environment Setup

Create separate webhooks for different environments:

{
  "url": "https://dev.example.com/webhooks",
  "method": "post",
  "status": "active",
  "events": ["workorder.created", "workorder.status.published"],
  "notificationEmail": "dev-team@example.com",
  "webhookAttribute": {
    "header": {
      "X-Environment": "development"
    }
  }
}
{
  "url": "https://staging.example.com/webhooks",
  "method": "post",
  "status": "active",
  "events": [
    "workorder.created",
    "workorder.status.published",
    "workorder.status.assigned",
    "workorder.status.work_done"
  ],
  "notificationEmail": "staging-alerts@example.com",
  "webhookAttribute": {
    "header": {
      "X-Environment": "staging"
    }
  }
}
{
  "url": "https://api.example.com/webhooks",
  "method": "post",
  "status": "active",
  "events": [
    "workorder.created",
    "workorder.status.published",
    "workorder.status.assigned",
    "workorder.status.checked_in",
    "workorder.status.work_done",
    "workorder.status.approved",
    "workorder.status.paid",
    "workorder.problem_reported"
  ],
  "notificationEmail": "prod-alerts@example.com",
  "webhookAttribute": {
    "header": {
      "Authorization": "Bearer prod-api-token",
      "X-Environment": "production"
    }
  }
}

Adding Custom Headers

Custom headers are sent with every webhook delivery:

Authentication Headers

{
  "webhookAttribute": {
    "header": {
      "Authorization": "Bearer your-api-token",
      "X-API-Key": "your-api-key"
    }
  }
}

Identifier Headers

{
  "webhookAttribute": {
    "header": {
      "X-Webhook-ID": "prod-wh-001",
      "X-Environment": "production",
      "X-Version": "v1",
      "X-Owner": "integrations-team"
    }
  }
}

Best Practice: Use custom headers for authentication instead of query parameters. Headers are encrypted in transit and stored encrypted in the database.


Event Selection Strategies

Strategy 1: Minimal (Core Events)

Subscribe only to critical lifecycle events:

{
  "events": [
    "workorder.status.published",
    "workorder.status.assigned",
    "workorder.status.work_done",
    "workorder.status.approved"
  ]
}

Use When: Building MVP or simple integration

Benefits: Minimal processing, easy to test, focused integration


Strategy 2: Comprehensive (All Status Changes)

Subscribe to complete status lifecycle:

{
  "events": [
    "workorder.status.published",
    "workorder.status.confirmed",
    "workorder.status.assigned",
    "workorder.status.on_my_way",
    "workorder.status.checked_in",
    "workorder.status.checked_out",
    "workorder.status.work_done",
    "workorder.status.approved",
    "workorder.status.paid",
    "workorder.status.cancelled"
  ]
}

Use When: Need complete visibility into work order progress

Benefits: Real-time dashboards, detailed tracking, comprehensive sync


Strategy 3: Activity-Focused

Subscribe to work order activities:

{
  "events": [
    "workorder.message_posted",
    "workorder.provider_upload",
    "workorder.task_completed",
    "workorder.schedule_updated",
    "workorder.problem_reported",
    "workorder.problem_resolved"
  ]
}

Use When: Monitoring provider activity and work progress

Benefits: Track communications, document uploads, task completion


Strategy 4: All Events

Subscribe to everything:

{
  "events": [
    "workorder.created",
    "workorder.routed",
    // ... all 33 events
  ]
}

Use When: Building comprehensive integration or analytics

Caution: High event volume, requires robust processing


Infrastructure as Code

Terraform Example

resource "fieldnation_webhook" "production" {
  url    = "https://api.example.com/webhooks"
  method = "post"
  status = "active"

  events = [
    "workorder.status.published",
    "workorder.status.assigned",
    "workorder.status.work_done",
    "workorder.status.approved"
  ]

  notification_email = "prod-alerts@example.com"

  custom_headers = {
    "Authorization" = "Bearer ${var.api_token}"
    "X-Environment" = "production"
  }
}

Script-Based Creation

create-webhook.js
const fetch = require('node-fetch');

async function createWebhook(config) {
  // Get access token
  const tokenResponse = await fetch(
    'https://api-sandbox.fndev.net/authentication/api/oauth/token',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'client_credentials',
        client_id: process.env.FN_CLIENT_ID,
        client_secret: process.env.FN_CLIENT_SECRET
      })
    }
  );

  const { access_token } = await tokenResponse.json();

  // Create webhook
  const webhookResponse = await fetch(
    'https://api-sandbox.fndev.net/api/v1/webhooks',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${access_token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(config)
    }
  );

  const webhook = await webhookResponse.json();

  console.log('Webhook created:', webhook.result.webhookId);
  console.log('Secret:', webhook.result.secret);

  return webhook.result;
}

// Usage
createWebhook({
  url: 'https://your-endpoint.com/webhooks',
  method: 'post',
  status: 'active',
  events: ['workorder.status.published', 'workorder.status.assigned'],
  notificationEmail: 'alerts@example.com'
});

Best Practices

Start Inactive for Testing

Create webhooks in inactive state for safe testing:

{
  "status": "inactive",
  // ... other config
}

Activate after verifying endpoint:

curl -X PUT https://api-sandbox.fndev.net/api/v1/webhooks/wh_abc123 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "active"}'

Use Descriptive Notification Emails

{
  "notificationEmail": "webhook-prod-team-integrations@example.com"
}

Benefits:

  • Easy to identify which webhook failed
  • Route to correct team
  • Track multiple environments

Generate Strong Secrets

const crypto = require('crypto');
const uuid = require('uuid');

// Option 1: UUID v4
const secret = uuid.v4();

// Option 2: Random hex
const secret = crypto.randomBytes(32).toString('hex');

Document Your Webhooks

Maintain a registry:

| Webhook ID | Environment | Events | Owner | Purpose |
|------------|-------------|--------|-------|---------|
| wh_prod_01 | Production | Status changes | Integrations | Salesforce sync |
| wh_prod_02 | Production | All events | Analytics | Data warehouse |
| wh_dev_01 | Development | Core events | Dev Team | Local testing |

Last updated on

Webhook Lifecycle

Understanding webhook states (active, inactive, archived), transitions, history tracking, and change auditing.

Security Best Practices

Secure your webhook endpoints with HMAC-SHA256 signature verification, IP whitelisting, HTTPS, and custom authentication headers.

On this page

Prerequisites
Method 1: Web UI (Visual)
Navigate to Webhooks Dashboard
Click "Create New"
Configure Basic Settings
Select Events
Configure Advanced Settings (Optional)
Review & Create
UI Configuration Example
Method 2: REST API (Programmatic)
Step 1: Get OAuth Access Token
Step 2: Create Webhook
Step 3: Verify Webhook Created
Request Body Reference
Required Fields
Optional Fields
Configuration Examples
Minimal Configuration
Production-Ready Configuration
Multi-Environment Setup
Adding Custom Headers
Authentication Headers
Identifier Headers
Event Selection Strategies
Strategy 1: Minimal (Core Events)
Strategy 2: Comprehensive (All Status Changes)
Strategy 3: Activity-Focused
Strategy 4: All Events
Infrastructure as Code
Terraform Example
Script-Based Creation
Best Practices
Start Inactive for Testing
Use Descriptive Notification Emails
Generate Strong Secrets
Document Your Webhooks