Skip to content

Webhook Configuration

Manage your agency's webhook configuration through the REST API. All endpoints require authentication with an agent token that has an active agency.

Base path: /v1/agency/webhooks

Endpoints

Update Configuration

Create or update your webhook configuration.

PUT /v1/agency/webhooks/config

Request Body:

Field Type Required Description
webhookUrl string Yes HTTPS URL to receive webhook deliveries
enabled boolean Yes Whether webhook delivery is active
subscribedEventTypes string[] Yes Array of event types to subscribe to

Example Request:

curl -X PUT https://api.fixify.co.za/v1/agency/webhooks/config \
  -H "authorization: <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://your-server.com/webhooks/fixify",
    "enabled": true,
    "subscribedEventTypes": [
      "job_created",
      "job_completed",
      "property_created",
      "quote_approved",
      "invoice_approved"
    ]
  }'

Example Response:

{
    "id": "config-id",
    "webhookUrl": "https://your-server.com/webhooks/fixify",
    "signingSecret": "a1b2c3d4e5f6...",
    "enabled": true,
    "subscribedEventTypes": [
        "job_created",
        "job_completed",
        "property_created",
        "quote_approved",
        "invoice_approved"
    ]
}

Store the signing secret securely

The signingSecret is returned in full only on creation and rotation. Store it securely — you'll need it to verify webhook signatures.


Get Configuration

Retrieve the current webhook configuration. The signing secret is masked.

GET /v1/agency/webhooks/config

Example Response:

{
    "id": "config-id",
    "webhookUrl": "https://your-server.com/webhooks/fixify",
    "signingSecret": "fixify_whsec_••••••••c3d4",
    "enabled": true,
    "subscribedEventTypes": ["job_created", "job_completed"]
}

Rotate Signing Secret

Generate a new signing secret. The previous secret is immediately invalidated.

POST /v1/agency/webhooks/config/rotate-secret

Example Response:

{
    "signingSecret": "new-secret-value-here..."
}

Tip

After rotating, update your webhook receiver with the new secret immediately to avoid failed signature verifications.


Test Webhook

Send a test event to your configured webhook URL to verify connectivity.

POST /v1/agency/webhooks/config/test

Example Response:

{
    "success": true,
    "statusCode": 200,
    "message": "Webhook test delivered successfully"
}

If the test fails:

{
    "success": false,
    "statusCode": 500,
    "message": "Received HTTP 500"
}

List Deliveries

Retrieve webhook delivery history for your agency.

GET /v1/agency/webhooks/deliveries

Query Parameters:

Parameter Type Description
status string Filter by status: pending, success, failed
limit number Maximum results to return (default: 20)

Example Response:

{
    "deliveries": [
        {
            "id": "delivery-id",
            "eventType": "job_created",
            "entityType": "job",
            "entityId": "job-123",
            "status": "success",
            "attempt": 1,
            "lastAttemptAt": 1718000000000,
            "deliveredAt": 1718000000000,
            "lastResponseCode": 200
        }
    ]
}

Get Delivery Detail

Retrieve full details for a specific delivery.

GET /v1/agency/webhooks/deliveries/:id

Example Response:

{
    "id": "delivery-id",
    "webhookId": "whdel_delivery-id",
    "eventId": "event-123",
    "eventType": "job_created",
    "entityType": "job",
    "entityId": "job-123",
    "parentEntityId": null,
    "createdById": "agent-456",
    "createdByRole": "Agent",
    "payload": { "id": "job-123", "name": "Fix leaking tap" },
    "status": "success",
    "attempt": 1,
    "maxAttempts": 5,
    "lastAttemptAt": 1718000000000,
    "nextRetryAt": null,
    "lastResponseCode": 200,
    "lastErrorMessage": null,
    "deliveredAt": 1718000000000
}

Replay Delivery

Manually re-enqueue a failed delivery for another attempt.

POST /v1/agency/webhooks/deliveries/:id/replay

Example Response:

{
    "message": "Delivery replayed successfully",
    "deliveryId": "delivery-id"
}

Note

Replaying resets the delivery status to pending and re-enqueues it in the task queue. The attempt counter continues from where it left off.

URL Validation

Webhook URLs must meet the following requirements:

  • HTTPS only — HTTP URLs are rejected
  • Public IP — The resolved IP must not be in a private range (10.x, 172.16-31.x, 192.168.x, 127.x, etc.)
  • Valid hostname — Must resolve to a valid DNS address

This prevents SSRF attacks by blocking internal network access.