> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ofiniti.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Subscribe to FuelBoss events, understand the CloudEvents delivery format, and verify webhook signatures.

Webhooks allow you to receive real-time notifications about events in the FuelBoss system.

## Creating subscriptions

[Create a subscription](/api-reference/webhooks/creates-a-webhook-subscription) (`POST /v1/webhooks`) for the event types you list (see [CloudEvent types](#cloudevent-types) for the available values). A company can have at most 10 subscriptions, and the endpoint URL must use HTTPS.

* The `secret` field is optional but recommended: FuelBoss uses it to sign every delivery — see [Webhook security](#webhook-security).
* The `headers` field configures custom HTTP headers included in every delivery, useful for authenticating with API gateways such as Azure API Management (for example `Ocp-Apim-Subscription-Key`). At most 10 headers; keys up to 100 characters, values up to 1000 characters. The reserved names `X-Webhook-Signature`, `X-Event-Id`, `X-Event-Type`, `User-Agent`, and `Content-Type` cannot be used. Header values are write-only: responses return the configured names via `headerKeys` but never the values.
* Subscribe using the simple event type values (for example `nomination_cancelled`). Deliveries carry the full CloudEvents format in the `type` field (for example `net.fuelboss.nomination.cancelled`) — see [CloudEvent types](#cloudevent-types) for the mapping.

## Webhook delivery format

When events occur, FuelBoss sends POST requests to your registered webhook URLs using the CloudEvents v1.0 specification format. Each webhook delivery contains a CloudEvent envelope with standardized fields (`specversion`, `id`, `type`, `source`, `time`, `datacontenttype`) and the event-specific payload in the `data` field. The envelope, the request headers, and the payload of every event — including field-level descriptions and a realistic example — are documented on the [webhook event reference pages](/api-reference/webhook-events/nomination-created).

**Important Notes:**

* All webhook deliveries use POST method with `Content-Type: application/json`
* The `id` field identifies the event: retries of the same event carry the same `id`, so use it for idempotency checking
* The `type` field uses CloudEvents format. See [CloudEvent Types](#cloudevent-types) for the mapping between subscription values and delivery type strings
* Field names inside the `data` payload are PascalCase (for example `ClientReference`), unlike the camelCase field names used by the REST API endpoints
* Timestamps are always in ISO 8601 format with UTC timezone
* Your webhook endpoint must respond with 2xx status code within 10 seconds
* Failed deliveries are retried with exponential backoff for up to 24 hours
* Any custom headers configured on the subscription are included in every webhook delivery alongside the standard headers
* Webhook deliveries originate from fixed IP addresses per environment. If your firewall or API gateway requires IP allowlisting, use the following addresses:
  * **Production:** `72.144.19.232`
  * **Demo:** `9.141.22.123`

***

## CloudEvent types

Mapping between webhook subscription event types and CloudEvent delivery type strings:

| Subscription Value (when creating webhook) | CloudEvent Type (in delivery `type` field) | Description |
| - | - | - |
| [nomination\_created](/api-reference/webhook-events/nomination-created) | net.fuelboss.nomination.created | Nomination has been created |
| [nomination\_cancelled](/api-reference/webhook-events/nomination-cancelled) | net.fuelboss.nomination.cancelled | Nomination has been cancelled |
| [nomination\_bunkering\_location\_changed](/api-reference/webhook-events/bunkering-location-changed) | net.fuelboss.nomination.bunkering\_location.changed | Nomination bunkering location has changed |
| [nomination\_fuel\_specification\_changed](/api-reference/webhook-events/fuel-specification-changed) | net.fuelboss.nomination.fuel\_specification.changed | Nomination fuel specification has changed |
| [nomination\_receiver\_vessel\_changed](/api-reference/webhook-events/receiver-vessel-changed) | net.fuelboss.nomination.receiver\_vessel.changed | Nomination receiver vessel has changed |
| [nomination\_supplier\_asset\_changed](/api-reference/webhook-events/supplier-asset-changed) | net.fuelboss.nomination.supplier\_asset.changed | Nomination supplier asset has changed |
| [nomination\_bunkering\_start\_time\_changed](/api-reference/webhook-events/bunkering-start-time-changed) | net.fuelboss.nomination.bunkering\_start\_time.changed | Nomination estimated bunkering start time (BST) has changed |
| [nomination\_bunkering\_end\_time\_changed](/api-reference/webhook-events/bunkering-end-time-changed) | net.fuelboss.nomination.bunkering\_end\_time.changed | Nomination estimated bunkering end time (estimated time of completion) has changed |
| [nomination\_contract\_changed](/api-reference/webhook-events/contract-changed) | net.fuelboss.nomination.contract.changed | Nomination contract has changed |
| [nomination\_company\_entity\_changed](/api-reference/webhook-events/company-entity-changed) | net.fuelboss.nomination.company\_entity.changed | Nomination supplier company entity has changed |
| [nomination\_counterpart\_entity\_changed](/api-reference/webhook-events/counterpart-entity-changed) | net.fuelboss.nomination.counterpart\_entity.changed | Nomination counterpart entity has changed |
| [nomination\_draft\_upserted](/api-reference/webhook-events/draft-nomination-upserted) | net.fuelboss.nomination.draft.upserted | Draft nomination has been created or updated |
| [operation\_started](/api-reference/webhook-events/operation-started) | net.fuelboss.operation.started | Bunkering operation has started |
| [operation\_ended](/api-reference/webhook-events/operation-ended) | net.fuelboss.operation.ended | Bunkering operation has ended |

**Note:** When creating webhook subscriptions, use the simple subscription values (left column). When processing webhook deliveries, parse the CloudEvent type strings (middle column) from the `type` field. Each subscription value links to the reference page documenting that event's delivery, envelope, and payload.

***

## Webhook security

### Signature verification

When creating a webhook subscription with a `secret`, FuelBoss signs each webhook delivery with HMAC-SHA256. The signature is included in the `X-Webhook-Signature` header as a Base64-encoded string.

**To verify a webhook delivery:**

1. Extract the `X-Webhook-Signature` header value
2. Compute HMAC-SHA256 of the raw request body using your secret
3. Base64-encode the computed hash
4. Compare the computed signature with the header value (use constant-time comparison)

### Best practices

* Always use HTTPS URLs for webhook endpoints
* Verify webhook signatures to ensure authenticity
* Use the CloudEvent `id` field for idempotency to handle duplicate deliveries
* Respond with 2xx status code quickly (under 10 seconds)
* Process webhook payloads asynchronously if needed
* Log webhook deliveries for debugging and audit purposes
* Implement exponential backoff if you need to retry processing
* Configure firewall or API gateway IP allowlisting for webhook source IPs (see [Webhook Delivery Format](#webhook-delivery-format))


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.