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

Payload Customization

Transform webhook payloads and create dynamic URLs to match your system's exact requirements. Eliminate middleware with JSONata expressions.


Overview

Field Nation webhooks now support customizable payloads and dynamic URLs, giving you complete control over how webhook data is structured and delivered.

Loading diagram...

What You Can Do

Transform Payloads

Restructure webhook data to match your system's expected format using JSONata expressions.

Dynamic URLs

Include event data in webhook URLs for intelligent routing (e.g., route by region or company).

Filter Fields

Send only the fields you need — reduce payload size and processing overhead.

Rename Fields

Match your system's naming conventions without building middleware.


Why Customize Payloads?

The Problem

Without customization, integrating with external systems requires:

  1. Middleware servers to transform Field Nation's payload format
  2. Extra development time to map fields between systems
  3. Infrastructure costs to maintain translation services
  4. Processing delays from additional network hops

The Solution

With payload customization, transformations happen at the source:

BeforeAfter
Build middleware to transformTransform at delivery
Maintain translation serversNo extra infrastructure
One fixed payload formatUnlimited custom formats
Static webhook URLsDynamic, data-driven URLs

Real-World Use Cases

Challenge: ServiceNow expects incident tickets in a specific format with custom field names.

JSONata Script:

{
  "u_external_ticket_id": $string($.workorder.id),
  "short_description": $.workorder.title,
  "state": $.workorder.status.name = "Work Done" ? "6" : "2",
  "assignment_group": "Field Services",
  "u_technician": $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name,
  "u_client_company": $.workorder.company.name,
  "work_notes": "Status updated via Field Nation at " & $.timestamp
}

Result: Direct webhook delivery to ServiceNow without middleware.

Challenge: Route work orders to region-specific endpoints automatically.

Dynamic URL Template:

https://{{$.workorder.location.country}}.api.company.com/workorders

Result:

  • US work orders → us.api.company.com/workorders
  • UK work orders → uk.api.company.com/workorders
  • CA work orders → ca.api.company.com/workorders

Challenge: Send formatted notifications to Slack when work orders complete.

JSONata Script:

{
  "text": "Work Order #" & $string($.workorder.id) & " - " & $.workorder.status.name,
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*" & $.workorder.title & "*\nStatus: " & $.workorder.status.name & "\nTechnician: " & $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name
      }
    }
  ]
}

Result: Native Slack notifications without a middleware service.

Challenge: A 15-year-old ERP only accepts flat JSON with uppercase field names.

JSONata Script:

{
  "WORK_ORDER_ID": $.workorder.id,
  "WORK_ORDER_TITLE": $.workorder.title,
  "COMPANY_NAME": $.workorder.company.name,
  "TECHNICIAN_NAME": $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name,
  "STATUS": $.workorder.status.name
}

Result: Direct integration with legacy systems that can't be modified.

Challenge: Data team needs webhook events in a format optimized for their data warehouse.

JSONata Script:

{
  "event_type": $.event.name,
  "event_timestamp": $.timestamp,
  "workorder_id": $.workorder.id,
  "company_id": $.workorder.company.id,
  "status": $.workorder.status.name,
  "location_state": $.workorder.location.state
}

Result: Webhook data flows directly into analytics pipeline without ETL processing.


Transformation Options

JSONata Expressions (Recommended)

JSONata is a powerful query and transformation language for JSON data.

Why JSONata? It's purpose-built for JSON transformation, has a concise syntax, and supports complex operations like filtering, sorting, and aggregation.

Basic Field Selection

{
  "order_id": $.workorder.id,
  "title": $.workorder.title,
  "status": $.workorder.status.name
}

Concatenating Fields

{
  "technician_name": $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name,
  "location": $.workorder.location.city & ", " & $.workorder.location.state
}

Conditional Logic

{
  "order_id": $.workorder.id,
  "is_complete": $.workorder.status.name = "Work Done",
  "priority": $.workorder.status.name = "At Risk" ? "high" : "normal",
  "state_code": $.workorder.status.name = "Work Done" ? "6" : 
                $.workorder.status.name = "Approved" ? "7" : "2"
}

Accessing Arrays

{
  "work_order_id": $.workorder.id,
  "po_number": $.workorder.custom_fields.results[name="PO Number"].value,
  "tags": $.workorder.tags.results.name,
  "has_priority_tag": "Priority" in $.workorder.tags.results.name
}

Built-in Functions

{
  "work_order_id": $string($.workorder.id),
  "title_uppercase": $uppercase($.workorder.title),
  "timestamp": $now(),
  "scheduled_date": $substringBefore($.workorder.schedule.start.utc, "T")
}

Static JSON Merge

For simpler use cases, merge static fields into every webhook payload:

{
  "source": "field-nation",
  "environment": "production",
  "api_version": "3.0",
  "integration_id": "your-integration-id"
}

This adds the static fields to the original payload without transforming it.


Dynamic URL Templates

Include values from the webhook payload in your endpoint URL using template expressions.

Template Syntax

https://api.example.com/workorders/{{$.workorder.id}}/updates

Templates use {{ expression }} syntax where expression is a JSONata path.

Common Patterns

Restriction: Templates are not allowed in the domain/origin part of the URL for security reasons. https://{{$.malicious}}.example.com is not permitted.


Payload Field Reference

All webhook events include these fields that you can use in transformations:

Root Level

PathTypeDescription
$.event.namestringEvent name (e.g., workorder.status.work_done)
$.event.paramsobjectEvent-specific parameters
$.timestampstringISO 8601 timestamp when event occurred
$.triggered_by_user.idnumberUser ID who triggered the event

Work Order Core

PathTypeDescription
$.workorder.idnumberUnique work order ID
$.workorder.titlestringWork order title
$.workorder.descriptionstringDetailed description
$.workorder.status.idnumberStatus ID
$.workorder.status.namestringStatus name

Company & People

PathTypeDescription
$.workorder.company.idnumberBuyer company ID
$.workorder.company.namestringBuyer company name
$.workorder.manager.first_namestringManager first name
$.workorder.manager.last_namestringManager last name
$.workorder.assignee.idnumberAssigned provider ID
$.workorder.assignee.first_namestringProvider first name
$.workorder.assignee.last_namestringProvider last name

Location

PathTypeDescription
$.workorder.location.citystringCity
$.workorder.location.statestringState/Province
$.workorder.location.zipstringZIP/Postal code
$.workorder.location.countrystringCountry code

Schedule & Pay

PathTypeDescription
$.workorder.schedule.start.utcstringScheduled start (UTC)
$.workorder.schedule.end.utcstringScheduled end (UTC)
$.workorder.pay.typestringPay type (fixed, hourly, etc.)
$.workorder.pay.base.amountnumberBase pay amount

Custom Fields & Tags

PathTypeDescription
$.workorder.custom_fields.resultsarrayCustom field objects
$.workorder.custom_fields.results[n].namestringField name
$.workorder.custom_fields.results[n].valuestringField value
$.workorder.tags.resultsarrayTag objects
$.workorder.tags.results[n].namestringTag name

Setting Up Payload Customization

Create or Edit a Webhook

Navigate to Webhooks Dashboard and create a new webhook or edit an existing one.

Enable Payload Override

Check the "Override default payload" option to enable customization.

Select Script Language

Choose your transformation approach:

  • JSONata (recommended) — Dynamic expressions for complex transformations
  • JSON — Static field merge for simple additions

Write Your Transformation Script

Enter your JSONata expression or JSON object:

{
  "ticket_id": $.workorder.id,
  "title": $.workorder.title,
  "status": $.workorder.status.name,
  "technician": $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name
}

Add Dynamic URL (Optional)

If needed, update your webhook URL to include template expressions:

https://api.example.com/workorders/{{$.workorder.id}}

Save and Test

Save the webhook configuration and trigger a test event to verify the transformation works correctly.


Best Practices

Start Simple

Begin with basic field selection, then add complexity as needed:

// Start here
{ "id": $.workorder.id, "status": $.workorder.status.name }

// Then expand
{
  "id": $.workorder.id,
  "status": $.workorder.status.name,
  "company": $.workorder.company.name,
  "technician": $.workorder.assignee.first_name & " " & $.workorder.assignee.last_name
}

Handle Missing Fields

Use the coalesce operator to provide defaults:

{
  "assignee_name": $.workorder.assignee.first_name ? 
    ($.workorder.assignee.first_name & " " & $.workorder.assignee.last_name) : 
    "Unassigned"
}

Test Before Production

Use the webhook test feature to validate transformations before enabling in production.

Keep Original Payloads

Original payloads are automatically preserved in Field Nation for debugging and re-delivery. You can access them through the delivery logs.

Debugging Tip: If a transformation fails, the original payload is still available in the delivery log details. Use this to diagnose and fix your script.


Troubleshooting


API Configuration

When creating or updating webhooks via API, include the webhookScript field:

curl -X POST https://api.fieldnation.com/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.example.com/workorders/{{$.workorder.id}}",
    "method": "post",
    "status": "active",
    "events": ["workorder.status.work_done"],
    "webhookScript": {
      "scriptLanguage": "jsonata",
      "script": "{ \"id\": $.workorder.id, \"status\": $.workorder.status.name }",
      "enabled": true
    }
  }'

webhookScript Fields

FieldTypeDescription
scriptLanguagestring"jsonata" or "json"
scriptstringThe transformation script
enabledbooleanToggle transformation on/off

Summary

Payload customization eliminates the need for middleware by transforming data at the source:

CapabilityBenefit
JSONata transformationsRestructure data to match any system
Dynamic URLsRoute webhooks based on event content
Enable/disable toggleTest without deleting configurations
Original payload storageDebug with full context

Bottom line: Your webhooks, your format. No middleware required.

Last updated on

Testing Webhooks

Test webhooks locally using ngrok, request inspectors, and mock payloads. Strategies for development, staging, and production testing.

API Reference Overview

Complete API documentation for Field Nation Webhooks v3 including authentication, base URLs, endpoints, and best practices.

On this page

Overview
What You Can Do
Why Customize Payloads?
The Problem
The Solution
Real-World Use Cases
Transformation Options
JSONata Expressions (Recommended)
Basic Field Selection
Concatenating Fields
Conditional Logic
Accessing Arrays
Built-in Functions
Static JSON Merge
Dynamic URL Templates
Template Syntax
Common Patterns
Payload Field Reference
Root Level
Work Order Core
Company & People
Location
Schedule & Pay
Custom Fields & Tags
Setting Up Payload Customization
Create or Edit a Webhook
Enable Payload Override
Select Script Language
Write Your Transformation Script
Add Dynamic URL (Optional)
Save and Test
Best Practices
Start Simple
Handle Missing Fields
Test Before Production
Keep Original Payloads
Troubleshooting
API Configuration
webhookScript Fields
Summary