Reonic Webhooks API

Webhooks notify your systems the moment something happens in Reonic. For example when a project is created or an offer is signed. Instead of repeatedly polling the API for changes, you give Reonic a URL and we send an HTTPS `POST` request to it whenever one of the events you selected occurs. The receiving URL does not have to be your own server. A webhook trigger from an automation tool works just as well. For example a "Webhooks by Zapier" trigger, an n8n Webhook node, or a Make "Custom webhook". ### Set up a webhook 1. Get the URL that should receive events — from your own service, or from your automation tool's webhook trigger step. It must be a public `https://` URL; URLs that resolve to private or internal addresses are rejected. 2. In the Reonic Portal, open the webhook settings (Settings > API / Developers > Webhooks), enter the URL, choose the events you want to receive, and save. 3. Send a test event from the same settings to confirm deliveries arrive (see [**Test events**](#webhooks-test-events) below). Saving also generates a signing secret (`whsec_…`), shown in the same settings. You only need it to verify signatures (recommended, see [**Verify signatures**](#webhooks-verify-signatures) below). The secret can be rotated there as well; rotation takes effect immediately and only one secret is valid at a time. Your endpoint must accept JSON `POST` requests (sent with `Content-Type: application/json`), must not redirect, and must respond within 5 seconds. Acknowledge first and process asynchronously if you need more time. ### Test events The Portal test action sends `X-Reonic-Event: test` with a `{ "message": … }` payload in the standard body shape (see [**Request format**](#webhooks-request-format) below). Use it to verify reachability and signature handling before enabling production events. Test deliveries are not retried and do not appear in the delivery log. Your endpoint's response is shown directly in the Portal instead. ### Request format Each delivery sends a JSON body with this shape: ```json { "version": 1, "type": "project_created", "occurredAt": "2026-01-01T12:00:00.000Z", "data": { /* event-specific payload, see the events below */ } } ``` Payloads are deliberately thin: they identify what happened and which resources were involved, but do not embed resource snapshots. Fetch the current state of an affected resource through the corresponding API v3 endpoint — for example, a `project_created` delivery carries a `projectId` to fetch via [**Residential Projects**](#tag/residential-projects) or [**Commercial Projects**](#tag/commercial-projects), depending on its `projectType`. Event metadata is also sent in headers: | Header | Meaning | |---|---| | `X-Reonic-Event` | Event type for this webhook delivery. Matches the `type` field in the body. | | `X-Reonic-Client-Id` | Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature. | | `X-Reonic-Event-Id` | Stable event id, identical across redeliveries of the same event. Use this as your idempotency key. | | `X-Reonic-Delivery-Id` | Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery. | | `X-Reonic-Timestamp` | Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`. | | `X-Reonic-Signature` | HMAC SHA-256 signature in the format `sha256=`, computed over `${timestamp}.${rawBody}`. | ### Verify signatures Verifying signatures is optional but strongly recommended: it proves a delivery was really sent by Reonic and not by someone who discovered your URL. If your tool cannot compute HMAC digests, keep your webhook URL secret and treat the data accordingly. Compute an HMAC SHA-256 digest with your webhook signing secret over `${timestamp}.${rawBody}`, then compare it to `X-Reonic-Signature`. Use the raw request body exactly as received, before JSON parsing. Reject deliveries whose `X-Reonic-Timestamp` is more than 5 minutes old to reduce replay risk — retries are signed freshly, so a legitimate delivery never carries an old timestamp. Code example: ```ts import { createHmac, timingSafeEqual } from "crypto"; const timestamp = request.headers["x-reonic-timestamp"]; const signature = request.headers["x-reonic-signature"]; const expected = Buffer.from("sha256=" + createHmac("sha256", secret) .update(`${timestamp}.${rawBody}`) .digest("hex")); const received = Buffer.from(signature); const isValid = expected.length === received.length && timingSafeEqual(expected, received); ``` ### Retries and idempotency Respond with any `2xx` status code once you have accepted the event — automation tools like Zapier and n8n do this for you. Every other response, as well as network errors and timeouts, is retried automatically, roughly 1 min, 5 min, 30 min, 2 h, 5 h, 12 h, 1 d, 2 d after the initial attempt. Delivery order is not guaranteed, and the same event may be delivered more than once, so store `X-Reonic-Event-Id` and ignore duplicates. > [!warning] > If all retries are exhausted, Reonic disables the webhook subscription and notifies your workspace's contact email. Re-enable it in the webhook settings once your endpoint is fixed. ### When deliveries fail The webhook settings in the Portal include a delivery log with every attempt, the response status or error we recorded, and the payload that was sent. Failed deliveries can be retried manually from there — including after you fix your endpoint and re-enable a disabled subscription. ### Compatibility The body's `version` (currently 1) only changes when the envelope shape itself — `version`, `type`, `occurredAt`, `data` — changes in a breaking way. New event types, new fields inside `data`, and new headers may appear without a version bump, so ignore anything you don't recognize.

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/reonic-webhooks-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

reonic-webhooks-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Reonic REST Api v3 Webhooks API
  description: 'The Reonic REST API v3 provides programmatic access to create and manage resources. The API follows REST principles and returns responses in JSON format. Authentication is required via an API key passed in the X-Authorization header.


    ## Errors


    All endpoints return errors with the same JSON shape:


    ```json

    { "message": "human-readable description" }

    ```


    `400` responses additionally include an `errors` field with per-field validation details.


    The HTTP status code identifies the cause:


    | Status  | Meaning | When |

    |--------|---------|------|

    | `400` | Bad Request | Path params, query string, or request body failed validation. Inspect `errors` for the field-level breakdown. |

    | `401` | Unauthorized | The `X-Authorization` header is missing, malformed, does not match an active API key, or belongs to a different API version. The response never indicates which check failed; check that the key matches the endpoint version. API v3 endpoints require a v3 key with the `rnc_v3_` prefix. |

    | `403` | Forbidden | The API key is read-only and the request targeted a write endpoint (`POST`). Issue a key with write access. |

    | `404` | Not Found | A resource referenced by a path id does not exist or is not visible to your workspace. |

    | `429` | Too Many Requests | The per-client rate limit was exceeded. See **Rate limiting** below. |

    | `500` | Internal Server Error | Unexpected failure. Safe to retry once; if it persists, contact support. |

    | `503` | Service Unavailable | A backing dependency is temporarily unavailable. Retry with exponential backoff. |


    ## Rate limiting


    Limits are shared across all API keys you hold and reset on a 1-minute window. Two buckets:


    | Bucket | Limit | Applies to |

    |--------|-------|------------|

    | `cached` | 500 / min | `GET` requests served from the response cache |

    | `uncached` | 30 / min | Cache misses, `GET` requests sent with `Reonic-Cache-Control: no-cache`, and all `POST` requests |


    Every response includes:


    - `X-RateLimit-Bucket` — `cached` or `uncached`

    - `X-RateLimit-Limit` — the bucket''s ceiling (`500` or `30`)

    - `X-RateLimit-Remaining` — calls left in the current window

    - `X-RateLimit-Reset` — Unix epoch seconds at which the window resets

    - `X-RateLimit-Policy` — `<limit>;w=60`


    `429` responses additionally set `Retry-After` (in seconds). Wait at least that long before retrying.


    ## Caching and Reonic-Cache-Control


    `GET` responses are cached for up to 1 hour. Identical requests (same path and query) on the same API key return the cached result. To force a fresh read, send `Reonic-Cache-Control: no-cache`; the response is then refreshed and re-cached. Forced refreshes count against the `uncached` rate-limit bucket.


    The standard `Cache-Control` header is not honored. Use `Reonic-Cache-Control` to control caching behavior.


    ## Authentication


    Every request must include your API key in the `X-Authorization` header:


    ```

    X-Authorization: <your-api-key>

    ```


    API keys are issued from the Reonic web app and look like `rnc_v3_…`. Send the full value, including the prefix.

    '
  version: 3.2.0
  contact:
    email: kontakt@reonic.de
    url: https://reonic.com
    name: Reonic GmbH
servers:
- url: '{apiBaseUrl}/rest/v3/'
security:
- X-Authorization: []
tags:
- name: Webhooks
  description: "Webhooks notify your systems the moment something happens in Reonic. For example when a project is created or an offer is signed. Instead of repeatedly polling the API for changes, you give Reonic a URL and we send an HTTPS `POST` request to it whenever one of the events you selected occurs.\n\nThe receiving URL does not have to be your own server. A webhook trigger from an automation tool works just as well. For example a \"Webhooks by Zapier\" trigger, an n8n Webhook node, or a Make \"Custom webhook\".\n\n### Set up a webhook\n\n1. Get the URL that should receive events — from your own service, or from your automation tool's webhook trigger step. It must be a public `https://` URL; URLs that resolve to private or internal addresses are rejected.\n2. In the Reonic Portal, open the webhook settings (Settings > API / Developers > Webhooks), enter the URL, choose the events you want to receive, and save.\n3. Send a test event from the same settings to confirm deliveries arrive (see [**Test events**](#webhooks-test-events) below).\n\nSaving also generates a signing secret (`whsec_…`), shown in the same settings. You only need it to verify signatures (recommended, see [**Verify signatures**](#webhooks-verify-signatures) below). The secret can be rotated there as well; rotation takes effect immediately and only one secret is valid at a time.\n\nYour endpoint must accept JSON `POST` requests (sent with `Content-Type: application/json`), must not redirect, and must respond within 5 seconds. Acknowledge first and process asynchronously if you need more time.\n\n<a id=\"webhooks-test-events\"></a>\n\n### Test events\n\nThe Portal test action sends `X-Reonic-Event: test` with a `{ \"message\": … }` payload in the standard body shape (see [**Request format**](#webhooks-request-format) below). Use it to verify reachability and signature handling before enabling production events. Test deliveries are not retried and do not appear in the delivery log. Your endpoint's response is shown directly in the Portal instead.\n\n<a id=\"webhooks-request-format\"></a>\n\n### Request format\n\nEach delivery sends a JSON body with this shape:\n\n```json\n{\n  \"version\": 1,\n  \"type\": \"project_created\",\n  \"occurredAt\": \"2026-01-01T12:00:00.000Z\",\n  \"data\": { /* event-specific payload, see the events below */ }\n}\n```\n\nPayloads are deliberately thin: they identify what happened and which resources were involved, but do not embed resource snapshots. Fetch the current state of an affected resource through the corresponding API v3 endpoint — for example, a `project_created` delivery carries a `projectId` to fetch via [**Residential Projects**](#tag/residential-projects) or [**Commercial Projects**](#tag/commercial-projects), depending on its `projectType`.\n\nEvent metadata is also sent in headers:\n\n| Header | Meaning |\n|---|---|\n| `X-Reonic-Event` | Event type for this webhook delivery. Matches the `type` field in the body. |\n| `X-Reonic-Client-Id` | Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature. |\n| `X-Reonic-Event-Id` | Stable event id, identical across redeliveries of the same event. Use this as your idempotency key. |\n| `X-Reonic-Delivery-Id` | Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery. |\n| `X-Reonic-Timestamp` | Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`. |\n| `X-Reonic-Signature` | HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`. |\n\n<a id=\"webhooks-verify-signatures\"></a>\n\n### Verify signatures\n\nVerifying signatures is optional but strongly recommended: it proves a delivery was really sent by Reonic and not by someone who discovered your URL. If your tool cannot compute HMAC digests, keep your webhook URL secret and treat the data accordingly.\n\nCompute an HMAC SHA-256 digest with your webhook signing secret over `${timestamp}.${rawBody}`, then compare it to `X-Reonic-Signature`. Use the raw request body exactly as received, before JSON parsing. Reject deliveries whose `X-Reonic-Timestamp` is more than 5 minutes old to reduce replay risk — retries are signed freshly, so a legitimate delivery never carries an old timestamp.\n\nCode example:\n\n```ts\nimport { createHmac, timingSafeEqual } from \"crypto\";\n\nconst timestamp = request.headers[\"x-reonic-timestamp\"];\nconst signature = request.headers[\"x-reonic-signature\"];\n\nconst expected = Buffer.from(\"sha256=\" + createHmac(\"sha256\", secret)\n  .update(`${timestamp}.${rawBody}`)\n  .digest(\"hex\"));\nconst received = Buffer.from(signature);\n\nconst isValid = expected.length === received.length && timingSafeEqual(expected, received);\n```\n\n### Retries and idempotency\n\nRespond with any `2xx` status code once you have accepted the event — automation tools like Zapier and n8n do this for you. Every other response, as well as network errors and timeouts, is retried automatically, roughly 1 min, 5 min, 30 min, 2 h, 5 h, 12 h, 1 d, 2 d after the initial attempt.\n\nDelivery order is not guaranteed, and the same event may be delivered more than once, so store `X-Reonic-Event-Id` and ignore duplicates.\n\n> [!warning]\n> If all retries are exhausted, Reonic disables the webhook subscription and notifies your workspace's contact email. Re-enable it in the webhook settings once your endpoint is fixed.\n\n### When deliveries fail\n\nThe webhook settings in the Portal include a delivery log with every attempt, the response status or error we recorded, and the payload that was sent. Failed deliveries can be retried manually from there — including after you fix your endpoint and re-enable a disabled subscription.\n\n### Compatibility\n\nThe body's `version` (currently 1) only changes when the envelope shape itself — `version`, `type`, `occurredAt`, `data` — changes in a breaking way. New event types, new fields inside `data`, and new headers may appear without a version bump, so ignore anything you don't recognize."
paths: {}
webhooks:
  residentialProject_created:
    post:
      operationId: webhookV2_residentialProject_created
      summary: Residential project created
      description: 'Sent when a residential project is created.


        **Deprecated** — subscribe to `project_created` instead: it covers both verticals and carries a `projectType`.'
      deprecated: true
      tags:
      - Webhooks
      parameters:
      - schema:
          type: string
          enum:
          - residentialProject_created
          description: Event type for this webhook delivery. Matches the `type` field in the body.
        required: true
        description: Event type for this webhook delivery. Matches the `type` field in the body.
        name: X-Reonic-Event
        in: header
      - schema:
          type: string
          format: uuid
          description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
        name: X-Reonic-Client-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
        name: X-Reonic-Event-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
        name: X-Reonic-Delivery-Id
        in: header
      - schema:
          type: string
          description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
          example: '1710000000'
        required: true
        description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
        name: X-Reonic-Timestamp
        in: header
      - schema:
          type: string
          description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
          example: sha256=ecb03c3a8d08e7137151335708afb85d5ccd756dcdc0ce21245827a56976524e
        required: true
        description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
        name: X-Reonic-Signature
        in: header
      requestBody:
        description: The message we send to your configured URL when this event happens.
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: number
                  enum:
                  - 1
                  description: Version of the public webhook body contract.
                  example: 1
                type:
                  type: string
                  enum:
                  - residentialProject_created
                  description: Event type for this delivery. Matches the `X-Reonic-Event` header.
                  example: residentialProject_created
                occurredAt:
                  type: string
                  format: date-time
                  description: When the event occurred, as an ISO 8601 timestamp.
                  example: '2026-01-01T15:30:00.000Z'
                data:
                  type: object
                  properties:
                    projectId:
                      type: string
                      format: uuid
                      description: ID of the project this event relates to. Fetch its current state via [**Residential Projects**](#tag/residential-projects).
                      example: 123e4567-e89b-12d3-a456-426614174000
                  required:
                  - projectId
              required:
              - version
              - type
              - occurredAt
              - data
              description: Webhook body for `residentialProject_created`.
      responses:
        2XX:
          description: Return any 2xx status code to acknowledge successful receipt.
  commercialProject_created:
    post:
      operationId: webhookV2_commercialProject_created
      summary: Commercial project created
      description: 'Sent when a commercial project is created.


        **Deprecated** — subscribe to `project_created` instead: it covers both verticals and carries a `projectType`.'
      deprecated: true
      tags:
      - Webhooks
      parameters:
      - schema:
          type: string
          enum:
          - commercialProject_created
          description: Event type for this webhook delivery. Matches the `type` field in the body.
        required: true
        description: Event type for this webhook delivery. Matches the `type` field in the body.
        name: X-Reonic-Event
        in: header
      - schema:
          type: string
          format: uuid
          description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
        name: X-Reonic-Client-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
        name: X-Reonic-Event-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
        name: X-Reonic-Delivery-Id
        in: header
      - schema:
          type: string
          description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
          example: '1710000000'
        required: true
        description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
        name: X-Reonic-Timestamp
        in: header
      - schema:
          type: string
          description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
          example: sha256=ecb03c3a8d08e7137151335708afb85d5ccd756dcdc0ce21245827a56976524e
        required: true
        description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
        name: X-Reonic-Signature
        in: header
      requestBody:
        description: The message we send to your configured URL when this event happens.
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: number
                  enum:
                  - 1
                  description: Version of the public webhook body contract.
                  example: 1
                type:
                  type: string
                  enum:
                  - commercialProject_created
                  description: Event type for this delivery. Matches the `X-Reonic-Event` header.
                  example: commercialProject_created
                occurredAt:
                  type: string
                  format: date-time
                  description: When the event occurred, as an ISO 8601 timestamp.
                  example: '2026-01-01T15:30:00.000Z'
                data:
                  type: object
                  properties:
                    projectId:
                      type: string
                      format: uuid
                      description: ID of the project this event relates to. Fetch its current state via [**Commercial Projects**](#tag/commercial-projects).
                      example: 123e4567-e89b-12d3-a456-426614174000
                  required:
                  - projectId
              required:
              - version
              - type
              - occurredAt
              - data
              description: Webhook body for `commercialProject_created`.
      responses:
        2XX:
          description: Return any 2xx status code to acknowledge successful receipt.
  residentialOffer_signatureRequested:
    post:
      operationId: webhookV2_residentialOffer_signatureRequested
      summary: Residential offer signature requested
      description: Sent when a signature is requested for a residential offer.
      tags:
      - Webhooks
      parameters:
      - schema:
          type: string
          enum:
          - residentialOffer_signatureRequested
          description: Event type for this webhook delivery. Matches the `type` field in the body.
        required: true
        description: Event type for this webhook delivery. Matches the `type` field in the body.
        name: X-Reonic-Event
        in: header
      - schema:
          type: string
          format: uuid
          description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
        name: X-Reonic-Client-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
        name: X-Reonic-Event-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
        name: X-Reonic-Delivery-Id
        in: header
      - schema:
          type: string
          description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
          example: '1710000000'
        required: true
        description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
        name: X-Reonic-Timestamp
        in: header
      - schema:
          type: string
          description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
          example: sha256=ecb03c3a8d08e7137151335708afb85d5ccd756dcdc0ce21245827a56976524e
        required: true
        description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
        name: X-Reonic-Signature
        in: header
      requestBody:
        description: The message we send to your configured URL when this event happens.
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: number
                  enum:
                  - 1
                  description: Version of the public webhook body contract.
                  example: 1
                type:
                  type: string
                  enum:
                  - residentialOffer_signatureRequested
                  description: Event type for this delivery. Matches the `X-Reonic-Event` header.
                  example: residentialOffer_signatureRequested
                occurredAt:
                  type: string
                  format: date-time
                  description: When the event occurred, as an ISO 8601 timestamp.
                  example: '2026-01-01T15:30:00.000Z'
                data:
                  type: object
                  properties:
                    projectId:
                      type: string
                      format: uuid
                      description: ID of the project this event relates to. Fetch its current state via [**Residential Projects**](#tag/residential-projects).
                      example: 123e4567-e89b-12d3-a456-426614174000
                    signatureRequestId:
                      type: string
                      format: uuid
                      description: ID of the signature request. Listed under `signatureRequests` on the [**Residential Projects**](#tag/residential-projects) detail response.
                      example: 123e4567-e89b-12d3-a456-426614174000
                    variantIds:
                      type: array
                      items:
                        type: string
                        format: uuid
                      description: The offer variants presented to the customer for signature.
                      example:
                      - 123e4567-e89b-12d3-a456-426614174000
                      - 123e4567-e89b-12d3-a456-426614174002
                    signatureOptions:
                      type: array
                      items:
                        type: object
                        properties:
                          variantId:
                            type: string
                            format: uuid
                            description: The offer variant this signature option belongs to.
                            example: 123e4567-e89b-12d3-a456-426614174000
                          paymentOptionId:
                            type:
                            - string
                            - 'null'
                            format: uuid
                            description: The payment option this signature option belongs to. `null` for legacy/default-payment documents.
                            example: 123e4567-e89b-12d3-a456-426614174002
                        required:
                        - variantId
                        - paymentOptionId
                      description: The variant/payment option combinations presented to the customer for signature.
                  required:
                  - projectId
                  - signatureRequestId
                  - variantIds
              required:
              - version
              - type
              - occurredAt
              - data
              description: Webhook body for `residentialOffer_signatureRequested`.
      responses:
        2XX:
          description: Return any 2xx status code to acknowledge successful receipt.
  residentialOffer_signed:
    post:
      operationId: webhookV2_residentialOffer_signed
      summary: Residential offer signed
      description: Sent when a residential offer is signed. A signed offer can still be withdrawn by the customer within the legal withdrawal period — also subscribe to `residentialOffer_signatureWithdrawn` if you act on this event.
      tags:
      - Webhooks
      parameters:
      - schema:
          type: string
          enum:
          - residentialOffer_signed
          description: Event type for this webhook delivery. Matches the `type` field in the body.
        required: true
        description: Event type for this webhook delivery. Matches the `type` field in the body.
        name: X-Reonic-Event
        in: header
      - schema:
          type: string
          format: uuid
          description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Id of the sending client. Stable across deliveries. If one endpoint receives webhooks from multiple clients, use this to pick the matching signing secret before verifying the signature.
        name: X-Reonic-Client-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Stable event id, identical across redeliveries of the same event. Use this as your idempotency key.
        name: X-Reonic-Event-Id
        in: header
      - schema:
          type: string
          format: uuid
          description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
          example: 123e4567-e89b-12d3-a456-426614174000
        required: true
        description: Unique id of this delivery attempt. Unlike the event id, it changes on every redelivery — reference it when reporting issues with a specific delivery.
        name: X-Reonic-Delivery-Id
        in: header
      - schema:
          type: string
          description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
          example: '1710000000'
        required: true
        description: Unix timestamp in seconds at which this delivery was signed. Changes on every redelivery — verify signatures against this value, not the body's `occurredAt`.
        name: X-Reonic-Timestamp
        in: header
      - schema:
          type: string
          description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
          example: sha256=ecb03c3a8d08e7137151335708afb85d5ccd756dcdc0ce21245827a56976524e
        required: true
        description: HMAC SHA-256 signature in the format `sha256=<hex>`, computed over `${timestamp}.${rawBody}`.
        name: X-Reonic-Signature
        in: header
      requestBody:
        description: The message we send to your configured URL when this event happens.
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: number
                  enum:
                  - 1
                  description: Version of the public webhook body contract.
                  example: 1
                type:
                  type: string
                  enum:
                  - residentialOffer_signed
                  description: Event type for this delivery. Matches the `X-Reonic-Event` header.
                  example: residentialOffer_signed
                occurredAt:
                  type: string
                  format: date-time
                  description: When the event occurred, as an ISO 8601 timestamp.
                  example: '2026-01-01T15:30:00.000Z'
                data:
                  type: object
                  properties:
                    projectId:
                      type: string
                      format: uuid
                      description: ID of the project this event relates to. Fetch its current state via [**Residential Projects**](#tag/residential-projects).
                      example: 123e4567-e89b-12d3-a456-426614174000
                    signatureRequestId:
                      type: string
                      format: uuid
                      description: ID of the signature request. Listed under `signatureRequests` on the [**Residential Projects**](#tag/residential-projects) detail response.
                      example: 123e4567-e89b-12d3-a456-426614174000
                    signedVariantId:
                      type: string
                      format: uuid
                      description: The offer variant the customer signed.
                      example: 123e4567-e89b-12d3-a456-426614174000
                    signedPaymentOptionId:
                      type:
                      - string
                      - 'null'
                      format: uuid
                      description: The payment option the customer signed. `null` for legacy/default-payment documents.
                      example: 123e4567-e89b-12d3-a456-426614174000
                  required:
                  - projectId
                  - signatureRequestId
                  - signedVariantId
              required:
              - version
              - type
              - occurredAt
              - data
              description: Webhook body for `residentialOffer_signed`.
      responses:
        2XX:
          description: Return any 

# --- truncated at 32 KB (105 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/reonic/refs/heads/main/openapi/reonic-webhooks-api-openapi.yml