API Reference

Complete documentation for WorkSkedge webhook integrations. Test endpoints live, view schemas, and integrate with your construction management workflow.

WorkSkedge Webhooks

WorkSkedge provides a powerful webhook system that enables seamless integration with your existing tools and workflows. Connect to Microsoft Dynamics 365, QuickBooks, custom applications, and more.

Inbound Webhooks

Send data to WorkSkedge from your systems. Create work orders, update projects, manage employees, and more via HTTP POST requests.

Outbound Webhooks

Receive real-time notifications from WorkSkedge when events occur. Get notified about work order updates, project changes, employee activity, and more.

Getting Started

1

Get Your API Key

Log in to your WorkSkedge dashboard and navigate to Settings → Integrations to generate your API key.

Open Dashboard
2

Choose Your Integration

Decide whether you need to send data to WorkSkedge (Inbound), receive notifications from WorkSkedge (Outbound), or both.

3

Review the Documentation

Use the tabs above to explore Inbound endpoints, Outbound webhook events, and the complete Event Catalog.

4

Test Your Integration

Use the interactive API explorer below to test endpoints with your API key and see live responses.

Interactive API Explorer

Test endpoints live, view request/response schemas, and generate code samples in multiple languages. Enter your API key to try it out.

Loading API documentation...

Rate Limits

To ensure fair usage and system stability, API requests are rate limited:

  • Inbound Webhooks: 1,000 requests per hour per API key
  • Outbound Webhooks: Unlimited (we send to your endpoints)
  • Burst Limit: Up to 50 requests per minute

Rate limit headers are included in all responses. Contact us if you need higher limits.

Need Help?

Our team is here to help you integrate WorkSkedge with your systems. Reach out if you have questions or need custom integration support.

Inbound Webhooks

Send data to WorkSkedge from your external systems. Create and update work orders, projects, employees, vendors, and more via simple HTTP POST requests.

Authentication

All inbound webhook requests must include your API key in the X-API-Key header. You can generate your API key from the WorkSkedge dashboard.

Authentication Header
curl -X POST https://app.workskedge.com/api/webhook/workorder \
  -H "X-API-Key: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{"workOrderNumber": "WO-12345", ...}'

Available Endpoints

POST
/api/webhook/workorder

Create Work Order

Create a new work order in WorkSkedge with comprehensive details including assignments, materials, and custom fields.

Request Body

work-order-request.json
{
  "workOrderNumber": "WO-12345",
  "projectId": "proj_abc123",
  "title": "Install HVAC System - Building A",
  "description": "Complete HVAC installation for commercial building",
  "priority": "high",
  "status": "scheduled",
  "scheduledStartDate": "2025-11-01T08:00:00Z",
  "scheduledEndDate": "2025-11-01T17:00:00Z",
  "assignedTo": ["emp_001", "emp_002"],
  "location": {
    "address": "123 Construction Ave",
    "city": "Seattle",
    "state": "WA",
    "zip": "98101",
    "latitude": 47.6062,
    "longitude": -122.3321
  },
  "customFields": {
    "permitNumber": "PERMIT-2025-001",
    "inspectionRequired": true,
    "clientPO": "PO-789456"
  }
}

Response

200 OK
{
  "success": true,
  "data": {
    "id": "wo_xyz789",
    "workOrderNumber": "WO-12345",
    "status": "scheduled",
    "createdAt": "2025-10-20T14:30:00Z",
    "url": "https://app.workskedge.com/workorders/wo_xyz789"
  }
}
POST
/api/webhook/project

Create Project

Create a new project in WorkSkedge with timeline, budget, and team assignments.

Request Body

project-request.json
{
  "projectNumber": "PROJ-2025-001",
  "name": "Downtown Office Building",
  "description": "Complete commercial office construction",
  "clientName": "Acme Corporation",
  "startDate": "2025-11-01",
  "endDate": "2026-06-30",
  "budget": 2500000,
  "projectManager": "emp_pm001",
  "status": "active"
}

Response

200 OK
{
  "success": true,
  "data": {
    "id": "proj_abc123",
    "projectNumber": "PROJ-2025-001",
    "status": "active",
    "createdAt": "2025-10-20T14:30:00Z"
  }
}
POST
/api/webhook/employee

Create Employee

Add a new employee to WorkSkedge with role, skills, and contact information.

POST
/api/webhook/vendor

Create Vendor

Register a new vendor or subcontractor in WorkSkedge.

POST
/api/webhook/timeoff

Submit Time Off Request

Create a new time off request for an employee.

Common Error Codes

400
Bad Request

Invalid request body or missing required fields

401
Unauthorized

Missing or invalid API key

429
Too Many Requests

Rate limit exceeded

200
Success

Request processed successfully

Outbound Webhooks

Receive real-time notifications from WorkSkedge when events occur in your account. Subscribe to events and receive HTTP POST requests to your endpoint URLs.

Setup & Configuration

Configure outbound webhooks in your WorkSkedge dashboard. Navigate to Settings → Webhooks to add endpoint URLs and subscribe to specific event types.

Configure Webhooks

Webhook Headers

All outbound webhook requests include the following headers for verification and processing:

X-Webhook-Signature

HMAC-SHA256 signature for verifying the request authenticity

X-Webhook-Timestamp

Unix timestamp when the webhook was sent (for replay protection)

X-Webhook-ID

Unique identifier for this webhook delivery

X-Webhook-Event

The event type that triggered this webhook

X-Webhook-Retry

Retry attempt number (0 for first attempt)

Signature Verification

Verify webhook authenticity by validating the X-Webhook-Signature header. This ensures the request came from WorkSkedge and hasn't been tampered with.

verify-signature.js
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret, timestamp) {
  const fiveMinutesAgo = Math.floor(Date.now() / 1000) - 300;
  if (timestamp < fiveMinutesAgo) {
    throw new Error('Webhook timestamp too old');
  }

  const signedPayload = `${timestamp}.${payload}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const timestamp = req.headers['x-webhook-timestamp'];
  const payload = JSON.stringify(req.body);

  try {
    if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET, timestamp)) {
      return res.status(401).json({ error: 'Invalid signature' });
    }

    console.log('Webhook verified:', req.body);
    res.status(200).json({ received: true });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});
verify_signature.py
import hmac
import hashlib
import time
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = 'your-webhook-secret'

def verify_webhook_signature(payload, signature, timestamp):
    five_minutes_ago = int(time.time()) - 300
    if int(timestamp) < five_minutes_ago:
        raise ValueError('Webhook timestamp too old')

    signed_payload = f"{timestamp}.{payload}"
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        signed_payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(signature, expected_signature)

@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Webhook-Signature')
    timestamp = request.headers.get('X-Webhook-Timestamp')
    payload = request.get_data(as_text=True)

    try:
        if not verify_webhook_signature(payload, signature, timestamp):
            return jsonify({'error': 'Invalid signature'}), 401

        data = request.get_json()
        print('Webhook verified:', data)
        return jsonify({'received': True}), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 400
verify-signature.php
<?php

define('WEBHOOK_SECRET', 'your-webhook-secret');

function verifyWebhookSignature($payload, $signature, $timestamp) {
    $fiveMinutesAgo = time() - 300;
    if ($timestamp < $fiveMinutesAgo) {
        throw new Exception('Webhook timestamp too old');
    }

    $signedPayload = $timestamp . '.' . $payload;
    $expectedSignature = hash_hmac('sha256', $signedPayload, WEBHOOK_SECRET);

    return hash_equals($signature, $expectedSignature);
}

$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$payload = file_get_contents('php://input');

try {
    if (!verifyWebhookSignature($payload, $signature, $timestamp)) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid signature']);
        exit;
    }

    $data = json_decode($payload, true);
    error_log('Webhook verified: ' . print_r($data, true));

    http_response_code(200);
    echo json_encode(['received' => true]);
} catch (Exception $e) {
    http_response_code(400);
    echo json_encode(['error' => $e->getMessage()]);
}
?>
test-webhook.sh
#!/bin/bash

WEBHOOK_URL="https://your-domain.com/webhook"
PAYLOAD='{"event":"workorder.created","data":{"id":"wo_123"}}'
TIMESTAMP=$(date +%s)
SECRET="your-webhook-secret"

SIGNATURE=$(echo -n "${TIMESTAMP}.${PAYLOAD}" | \
  openssl dgst -sha256 -hmac "$SECRET" | \
  sed 's/^.* //')

curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Signature: $SIGNATURE" \
  -H "X-Webhook-Timestamp: $TIMESTAMP" \
  -H "X-Webhook-Event: workorder.created" \
  -H "X-Webhook-ID: test_$(uuidgen)" \
  -H "X-Webhook-Retry: 0" \
  -d "$PAYLOAD"

Retry Logic

If your endpoint fails to respond with a 2xx status code, WorkSkedge will automatically retry delivery using exponential backoff:

1st
Immediate

First delivery attempt

2nd
1 minute

After initial failure

3rd
5 minutes

After second failure

4th
15 minutes

After third failure

5th
1 hour

Final attempt

After 5 failed attempts, the webhook delivery is marked as failed and you'll receive an alert. You can manually retry failed webhooks from the dashboard.

Security Best Practices

  • Always verify signatures to ensure webhooks are from WorkSkedge
  • Check timestamps to prevent replay attacks (reject requests older than 5 minutes)
  • Use HTTPS endpoints to encrypt data in transit
  • Store webhook secrets securely using environment variables
  • Respond quickly with a 200 status, then process asynchronously
  • Implement idempotency using the webhook ID to handle duplicate deliveries

Endpoint Requirements

Your webhook endpoint must meet these requirements:

  • Accept HTTP POST requests
  • Respond within 30 seconds
  • Return 2xx status code for successful receipt
  • Use HTTPS (HTTP endpoints are not supported)
  • Handle duplicate deliveries gracefully

Event Catalog

Browse all available webhook events in WorkSkedge. Subscribe to the events you need and receive real-time notifications when they occur.

Work Orders 6 events

Outbound workorder.created

Triggered when a new work order is created in WorkSkedge

Example Payload

{
  "event": "workorder.created",
  "timestamp": "2025-10-20T14:30:00Z",
  "data": {
    "id": "wo_xyz789",
    "workOrderNumber": "WO-12345",
    "title": "Install HVAC System",
    "status": "scheduled",
    "priority": "high",
    "projectId": "proj_abc123"
  }
}
Outbound workorder.updated

Triggered when a work order is updated (status, assignments, details, etc.)

Outbound workorder.deleted

Triggered when a work order is deleted or archived

Outbound workorder.started

Triggered when work begins on a work order

Outbound workorder.completed

Triggered when a work order is marked as completed

Outbound workorder.cancelled

Triggered when a work order is cancelled

Projects 3 events

Outbound project.created

Triggered when a new project is created

Outbound project.updated

Triggered when project details are updated

Outbound project.completed

Triggered when a project is marked as completed

Employees 4 events

Outbound employee.created

Triggered when a new employee is added to the system

Outbound employee.updated

Triggered when employee information is updated

Outbound employee.deleted

Triggered when an employee is removed from the system

Outbound employee.assigned

Triggered when an employee is assigned to a work order or project

Vendors 3 events

Outbound vendor.created

Triggered when a new vendor is registered

Outbound vendor.updated

Triggered when vendor information is updated

Outbound vendor.deleted

Triggered when a vendor is removed

Time Off 4 events

Outbound timeoff.requested

Triggered when an employee submits a time off request

Outbound timeoff.approved

Triggered when a time off request is approved

Outbound timeoff.denied

Triggered when a time off request is denied

Outbound timeoff.cancelled

Triggered when a time off request is cancelled

Reports 3 events

Outbound report.generated

Triggered when a scheduled report is generated

Outbound report.scheduled

Triggered when a new report schedule is created

Outbound report.failed

Triggered when report generation fails

Construction team collaboration

Stop Wasting Time on Scheduling Chaos

Join construction teams who have eliminated conflicts and improved efficiency. Start your free 60-day trial—no credit card required.