Niural · AsyncAPI Specification

Niural Webhooks

Version

View Spec View on GitHub CompanyPayrollHuman ResourcesEmployer of RecordContractor ManagementGlobal PaymentsInvoicingComplianceFintechAsyncAPIWebhooksEvents

AsyncAPI Specification

Raw ↑
generated: '2026-08-04'
method: searched
source: >-
  https://docs.niural.com/docs/webhook-events,
  https://docs.niural.com/docs/webhook-event-payload,
  https://docs.niural.com/docs/security,
  https://docs.niural.com/docs/create-webhook-key,
  https://docs.niural.com/docs/best-practices
spec_type: none
description: >-
  Niural documents a real webhook surface but publishes NO AsyncAPI (or any other
  machine-readable event contract) — the events, their payloads and the signature
  scheme exist only as prose and JSON samples in the ReadMe docs. This artifact is
  the harvested webhook catalog; it is deliberately NOT an authored AsyncAPI
  document, because Niural has not published one.
transport: HTTPS POST to a subscriber-configured endpoint
subscription:
  managed_in: Niural dashboard — Organization > Developer > Webhooks
  fields: [webhook name, description, metadata (free-form JSON), endpoint URL, events]
  event_selection: >-
    Niural currently supports only "All Events" as the subscription selector — a
    subscriber cannot filter server-side to a single event type despite the docs
    recommending subscribing only to what you need.
  docs: https://docs.niural.com/docs/create-webhook-key
security:
  signature_header: X-Niural-Signatures
  timestamp_header: X-Niural-Timestamp
  algorithm: HMAC-SHA256
  signed_payload: '{body}.{timestamp}'
  encoding: hex digest, comma-separated list of valid signatures
  key_rotation: >-
    The past 4 signing keys stay valid for 24 hours after rotation; generating a
    6th key invalidates the oldest.
  docs: https://docs.niural.com/docs/security
delivery:
  guarantee: at-least-once
  duplicates: >-
    Endpoints may receive the same event multiple times; consumers must
    deduplicate on their side.
  ack: Respond 200 OK immediately, then process asynchronously.
  reliability_note: >-
    Niural states delivery is not guaranteed and recommends reconciliation jobs
    that periodically re-pull state from the REST API.
payload_envelope:
  meta: {event_type: string, organization_id: uuid, tracking_id: string}
  resource: object — the full resource snapshot for the event
events:
- name: contract.status.updated
  domain: Contracts
  description: Triggered when a pay-on-demand contract's status is updated.
  resource: contract
  sample_fields:
  - contract_id
  - contract_status
  - contract_type
  - contract_title
  - contract_document
  - contractor_id
  - contractor_email
  - contractor_type
  - contractor_address
  - employer_id
  - notice_period_in_days
  - scope_of_work
  observed_statuses: [CONTRACTOR_SIGN_PENDING]
  rest_reconciliation: GET /contracts/{contract-id}
- name: invoice.status.updated
  domain: Invoices
  description: Triggered when an invoice status is updated.
  note: >-
    Documented inconsistently — the event table names it "Invoice.status.updated"
    while the sample payload's meta.event_type is "invoice.status.updated".
  resource: invoice
  sample_fields:
  - invoice_id
  - status
  - currency
  - total_amount
  - issued_date
  - due_date
  - invoice_items
  - payer_id
  - payer_email
  - payee_id
  - contract_id
  - contractor_id
  observed_statuses: [PAYMENT_PROCESSING, PAYMENT_PENDING]
  rest_reconciliation: GET /invoices/{invoice-id}
- name: transaction.status.updated
  domain: Transactions
  description: Triggered when a transaction status is changed.
  note: >-
    Documented inconsistently — the event table names it
    "transactions.status.updated" while the sample payload's meta.event_type is
    "transaction.status.updated".
  resource: transaction
  sample_fields:
  - associated_invoices
  - associated_payrolls
  - fee_amount
  - fee_breakdown
  - sub_total_amount
  rest_reconciliation: GET /transactions/{transaction-id}
gaps:
- No AsyncAPI document, no JSON Schema for any event payload, and no event
  catalogue endpoint — the payload shape is only inferable from three samples.
- Event names disagree between the events table and the payload samples
  (Invoice vs invoice, transactions vs transaction).
- Subscriptions cannot be filtered to a single event type.