AsyncAPI definition for Deel's webhook surface. Deel webhooks are HTTP POST deliveries from Deel to a subscriber-controlled `url` registered via the Deel Webhooks API (`POST /rest/v2/webhooks`). A subscription declares one or more `events` (event type names) and is signed with a subscriber-supplied `signing_key`. Each delivery is a JSON document with a top-level `data` object that contains `meta` (event metadata including `event_type`, `organization_id`, and on simulated deliveries `is_simulation: true`), a `resource` array carrying event-specific fields, and a top-level `timestamp` (ISO 8601). The exact shape of `resource` varies by event type; documented field names are modeled below and additional fields are permitted because Deel's public documentation does not exhaustively enumerate them. Every delivery carries three Deel-specific HTTP headers: `x-deel-signature` (HMAC-SHA256 of `"POST" + raw_payload_body` computed with the subscription `signing_key`), `x-deel-hmac-label` (identifies which signing key was used), and `x-deel-webhook-version` (API version used for serialization, typically `v2`). Deel publishes more than 100 webhook event types accessible via `GET /rest/v2/webhooks/events/types`; only those whose names appear verbatim in Deel's public developer documentation (https://developer.deel.com/api/webhooks/introduction, https://developer.deel.com/api/webhooks/events, https://developer.deel.com/llms-full.txt) are modeled here. Subscribers should call the events endpoint at runtime to discover the full, authoritative catalog and per-event `payload_example`. Fields the documentation does not describe are not invented in this spec.
View SpecView on GitHubHRPayrollGlobal HiringEORContractorsComplianceSCIMAsyncAPIWebhooksEvents
Channels
contract.created
subscribeonContractCreated
Contract created
A new contract has been created in Deel (EOR, contractor, or Global Payroll). Subscribe to mirror new hires into downstream systems.
contract.signed
subscribeonContractSigned
Contract signed
A contract has been signed by all required parties and is now in an active state. Commonly used to provision access and kick off onboarding workflows.
contract.terminated
subscribeonContractTerminated
Contract terminated
A contract has been terminated. Use for offboarding flows such as revoking app access, archiving records, and closing payroll cycles.
invoice.paid
subscribeonInvoicePaid
Invoice paid
An invoice (contractor invoice or EOR/PEO bill) has been marked as paid. Use to reconcile invoices in accounting/ERP systems.
payment.completed
subscribeonPaymentCompleted
Payment completed
A Deel-initiated payment to a worker, contractor, or supplier has completed end-to-end. Use to confirm payouts and trigger notification flows.
eor.payslips.available
subscribeonEorPayslipsAvailable
EOR payslips available
EOR payslips are available for an employee or pay cycle. Use to notify employees or trigger downstream archival.
eor.amendment.status.updated
subscribeonEorAmendmentStatusUpdated
EOR amendment status updated
The status of an EOR contract amendment changed (e.g. moved into `EOR_AMENDMENT_V2_CLIENT_ACTIVE`). Use to track the amendment lifecycle without polling.
Messages
✉
ContractCreated
contract.created
A contract was created.
✉
ContractSigned
contract.signed
A contract was signed.
✉
ContractTerminated
contract.terminated
A contract was terminated.
✉
InvoicePaid
invoice.paid
An invoice was paid.
✉
PaymentCompleted
payment.completed
A payment has been completed end-to-end.
✉
EorPayslipsAvailable
eor.payslips.available
EOR payslips are available.
✉
EorAmendmentStatusUpdated
eor.amendment.status.updated
An EOR amendment's status changed.
Servers
https
subscriber{webhookUrl}
The HTTPS endpoint that the webhook subscriber registers with Deel via `POST /rest/v2/webhooks` (`url` field). Deel delivers every event this subscription opts into to this URL via HTTP POST with a JSON body. Endpoints must respond with a 2xx status within 30 seconds or Deel retries with exponential backoff (up to 10 attempts before the subscription is automatically disabled).
asyncapi: '2.6.0'
info:
title: Deel Webhooks
version: 'v2'
description: |
AsyncAPI definition for Deel's webhook surface. Deel webhooks are HTTP
POST deliveries from Deel to a subscriber-controlled `url` registered
via the Deel Webhooks API (`POST /rest/v2/webhooks`). A subscription
declares one or more `events` (event type names) and is signed with a
subscriber-supplied `signing_key`.
Each delivery is a JSON document with a top-level `data` object that
contains `meta` (event metadata including `event_type`,
`organization_id`, and on simulated deliveries `is_simulation: true`),
a `resource` array carrying event-specific fields, and a top-level
`timestamp` (ISO 8601). The exact shape of `resource` varies by event
type; documented field names are modeled below and additional fields
are permitted because Deel's public documentation does not exhaustively
enumerate them.
Every delivery carries three Deel-specific HTTP headers:
`x-deel-signature` (HMAC-SHA256 of `"POST" + raw_payload_body` computed
with the subscription `signing_key`), `x-deel-hmac-label` (identifies
which signing key was used), and `x-deel-webhook-version` (API version
used for serialization, typically `v2`).
Deel publishes more than 100 webhook event types accessible via
`GET /rest/v2/webhooks/events/types`; only those whose names appear
verbatim in Deel's public developer documentation
(https://developer.deel.com/api/webhooks/introduction,
https://developer.deel.com/api/webhooks/events,
https://developer.deel.com/llms-full.txt) are modeled here. Subscribers
should call the events endpoint at runtime to discover the full,
authoritative catalog and per-event `payload_example`. Fields the
documentation does not describe are not invented in this spec.
contact:
name: Deel Developer Platform
url: https://developer.deel.com/
license:
name: Proprietary
url: https://www.deel.com/legal/
tags:
- name: Deel
- name: Webhooks
- name: Payroll
- name: HR
- name: EOR
- name: Contracts
defaultContentType: application/json
servers:
subscriber:
url: '{webhookUrl}'
protocol: https
description: |
The HTTPS endpoint that the webhook subscriber registers with Deel
via `POST /rest/v2/webhooks` (`url` field). Deel delivers every event
this subscription opts into to this URL via HTTP POST with a JSON
body. Endpoints must respond with a 2xx status within 30 seconds or
Deel retries with exponential backoff (up to 10 attempts before the
subscription is automatically disabled).
variables:
webhookUrl:
description: Subscriber-controlled URL configured on the Deel webhook subscription.
default: https://example.com/webhooks/deel
channels:
contract.created:
description: |
A new contract has been created in Deel (EOR, contractor, or Global
Payroll). Subscribe to mirror new hires into downstream systems.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: Contract created
operationId: onContractCreated
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/ContractCreated'
contract.signed:
description: |
A contract has been signed by all required parties and is now in an
active state. Commonly used to provision access and kick off
onboarding workflows.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: Contract signed
operationId: onContractSigned
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/ContractSigned'
contract.terminated:
description: |
A contract has been terminated. Use for offboarding flows such as
revoking app access, archiving records, and closing payroll cycles.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: Contract terminated
operationId: onContractTerminated
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/ContractTerminated'
invoice.paid:
description: |
An invoice (contractor invoice or EOR/PEO bill) has been marked as
paid. Use to reconcile invoices in accounting/ERP systems.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: Invoice paid
operationId: onInvoicePaid
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/InvoicePaid'
payment.completed:
description: |
A Deel-initiated payment to a worker, contractor, or supplier has
completed end-to-end. Use to confirm payouts and trigger
notification flows.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: Payment completed
operationId: onPaymentCompleted
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/PaymentCompleted'
eor.payslips.available:
description: |
EOR payslips are available for an employee or pay cycle. Use to
notify employees or trigger downstream archival.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: EOR payslips available
operationId: onEorPayslipsAvailable
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/EorPayslipsAvailable'
eor.amendment.status.updated:
description: |
The status of an EOR contract amendment changed (e.g. moved into
`EOR_AMENDMENT_V2_CLIENT_ACTIVE`). Use to track the amendment
lifecycle without polling.
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
subscribe:
summary: EOR amendment status updated
operationId: onEorAmendmentStatusUpdated
bindings:
http:
type: request
method: POST
bindingVersion: 0.3.0
message:
$ref: '#/components/messages/EorAmendmentStatusUpdated'
components:
messageTraits:
DeelWebhookHeaders:
headers:
type: object
properties:
Content-Type:
type: string
const: application/json
x-deel-signature:
type: string
description: |
HMAC-SHA256 signature of the raw request body, computed as
`HMAC-SHA256(signing_key, "POST" + raw_payload_body)`. Use the
`signing_key` configured on the webhook subscription and
compare in constant time before processing.
x-deel-hmac-label:
type: string
description: |
Identifies which signing key was used to compute
`x-deel-signature`. Useful when rotating webhook signing keys.
x-deel-webhook-version:
type: string
description: |
Deel API version used to serialize the payload (e.g. `v1` or
`v2`). Pinned by `api_version` at webhook creation.
example: v2
messages:
ContractCreated:
name: ContractCreated
title: contract.created
summary: A contract was created.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: contract.created
resource:
type: array
items:
$ref: '#/components/schemas/ContractCreatedResource'
ContractSigned:
name: ContractSigned
title: contract.signed
summary: A contract was signed.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: contract.signed
resource:
type: array
items:
$ref: '#/components/schemas/ContractResource'
ContractTerminated:
name: ContractTerminated
title: contract.terminated
summary: A contract was terminated.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: contract.terminated
resource:
type: array
items:
$ref: '#/components/schemas/ContractResource'
InvoicePaid:
name: InvoicePaid
title: invoice.paid
summary: An invoice was paid.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: invoice.paid
resource:
type: array
items:
$ref: '#/components/schemas/GenericResource'
PaymentCompleted:
name: PaymentCompleted
title: payment.completed
summary: A payment has been completed end-to-end.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: payment.completed
resource:
type: array
items:
$ref: '#/components/schemas/GenericResource'
EorPayslipsAvailable:
name: EorPayslipsAvailable
title: eor.payslips.available
summary: EOR payslips are available.
description: |
Module `payslips` (label `Payslips`). Triggered when EOR payslips
are available for delivery to employees. Full `resource` shape is
published by Deel via the `payload_example` field returned from
`GET /rest/v2/webhooks/events/types`.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- $ref: '#/components/schemas/WebhookEnvelope'
- type: object
properties:
data:
type: object
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: eor.payslips.available
resource:
type: array
items:
$ref: '#/components/schemas/GenericResource'
EorAmendmentStatusUpdated:
name: EorAmendmentStatusUpdated
title: eor.amendment.status.updated
summary: An EOR amendment's status changed.
description: |
Carries the amendment identifier, owning organization, and the
new status (e.g. `EOR_AMENDMENT_V2_CLIENT_ACTIVE`). For this event
type Deel delivers `resource` as a single object rather than an
array; subscribers should accept either shape.
contentType: application/json
traits:
- $ref: '#/components/messageTraits/DeelWebhookHeaders'
payload:
allOf:
- type: object
required:
- data
- timestamp
properties:
data:
type: object
required:
- meta
- resource
properties:
meta:
allOf:
- $ref: '#/components/schemas/EventMeta'
- type: object
properties:
event_type:
const: eor.amendment.status.updated
event_type_id:
type: string
description: UUID identifying the event type definition.
tracking_id:
type: string
description: Per-delivery tracking identifier used in Deel logs.
organization_name:
type: string
description: Display name of the receiving organization.
resource:
$ref: '#/components/schemas/EorAmendmentResource'
timestamp:
type: string
format: date-time
schemas:
WebhookEnvelope:
type: object
description: |
Standard Deel webhook envelope. Every delivery is a JSON document
whose top-level `data` object carries `meta` (event metadata) and
`resource` (event-specific data). A top-level `timestamp`
indicates when the event occurred in ISO 8601 format.
required:
- data
- timestamp
properties:
data:
type: object
required:
- meta
- resource
properties:
meta:
$ref: '#/components/schemas/EventMeta'
resource:
type: array
description: |
Event-specific resource payload. Shape varies by event
type. Documented field names are modeled per message;
additional fields are permitted because Deel's public
documentation does not exhaustively enumerate them.
items:
type: object
additionalProperties: true
timestamp:
type: string
format: date-time
description: ISO 8601 timestamp when the event occurred.
EventMeta:
type: object
description: Common envelope metadata included on every Deel webhook delivery.
required:
- event_type
- organization_id
properties:
event_type:
type: string
description: |
Canonical event type name (e.g. `contract.created`). Matches
one of the names returned from `GET /rest/v2/webhooks/events/types`.
organization_id:
type: string
description: Identifier of the Deel organization the event belongs to.
event_id:
type: string
description: Unique identifier for this individual event.
occurred_at:
type: string
format: date-time
description: ISO 8601 timestamp at which the underlying business event happened.
is_simulation:
type: boolean
description: |
Present and `true` when this delivery was generated by Deel's
webhook simulation feature (Developer Center → Webhooks →
Simulate, or `POST /rest/v2/webhooks/test`). Absent or `false`
for real events.
ContractCreatedResource:
type: object
description: |
Resource payload Deel documents for `contract.created`. Subscribers
should accept additional fields.
additionalProperties: true
properties:
contract_id:
type: string
description: Deel contract identifier.
worker_email:
type: string
format: email
description: Email address of the worker on the contract.
status:
type: string
description: |
Current contract status. Documented example values include
`pending`.
type:
type: string
description: |
Contract type. Documented example values include `eor`.
country:
type: string
description: ISO country code where the contract is hosted.
created_at:
type: string
format: date-time
description: ISO 8601 timestamp at which the contract was created.
ContractResource:
type: object
description: |
Generic contract resource. Deel does not publish a full field-level
schema for `contract.signed` and `contract.terminated`; subscribers
should rely on the `payload_example` retrieved from
`GET /rest/v2/webhooks/events/types` and accept additional fields.
additionalProperties: true
properties:
contract_id:
type: string
description: Deel contract identifier.
EorAmendmentResource:
type: object
description: |
Resource payload Deel documents for `eor.amendment.status.updated`.
Subscribers should accept additional fields.
additionalProperties: true
properties:
amendment_flow_id:
type: string
description: Identifier of the EOR amendment flow.
organization_id:
type: string
description: Identifier of the owning Deel organization.
status:
type: string
description: |
Current amendment status (e.g. `EOR_AMENDMENT_V2_CLIENT_ACTIVE`).
GenericResource:
type: object
description: |
Generic event-specific resource. Deel's public documentation does
not publish a field-level schema for this event; rely on the
`payload_example` returned from `GET /rest/v2/webhooks/events/types`
at runtime and accept additional fields.
additionalProperties: true