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

# Choose where your notifications go

> Changes who gets the emails, which events you want by email and by webhook, and the address of your webhook.
A key you leave out of the body is left as it was; send only what changes.

**Email.** `emailRecipients` is the list of addresses (at most five). While it is empty the emails about
invoices go to the billing emails of your billing profile (your contact email when there are none), and the
others to your contact email. The events about money and about the standing of your account are always
emailed, whatever `emailEvents` says; it narrows the others.

**Webhook.** `webhookUrl` is where Widgetic sends a signed `POST` for each event, so that your own system
can act on it (mark an invoice paid, warn your team that credits are low). The address must be `https` on the
standard port, on a public site, and must not redirect. Setting an address when you have no secret yet makes
one, and the answer carries it as `webhookSecret`: **keep it now, it is shown once**. `webhookEvents` narrows
what is sent.

Each call has a JSON body, `{ "id": "evt_...", "type": "invoice.paid", "createdAt": "...", "partnerId": "...",
"data": { ... } }` (`data` is the `data` of `PartnerNotification`), and these headers:
`webhook-id` (the same as `id`, and the same on every retry), `webhook-timestamp` (seconds since 1970) and
`webhook-signature` (`v1,` and a base64 HMAC-SHA256). It is the Standard Webhooks scheme, so any of its
libraries verifies it. By hand: take your secret without the `whsec_` prefix, decode it from base64, and sign
the text `<webhook-id>.<webhook-timestamp>.<the raw body>` with it; the header holds `v1,<base64 of the
result>` (two signatures separated by a space while a rotated secret overlaps). Reject a `webhook-timestamp`
that is more than five minutes old.

Answer with a 2xx status within ten seconds. Anything else is tried again, eight attempts in all over about
two days (`listPartnerNotificationDeliveries` shows each). Delivery is at least once: if your answer was lost
the same event arrives again with the same `id`, so drop what you have already handled by it.

Changing the settings needs an API key with full access: they decide where your notifications go.
The caller must be the person who administers the partner, or a Widgetic administrator.




## OpenAPI

````yaml /openapi/widgetic-api-public.json put /partners/{partnerId}/notifications/settings
openapi: 3.0.0
info:
  title: Widgetic API Gateway
  version: 1.0.0
  description: API documentation for the Widgetic API Gateway
  license:
    name: Widgetic Integration License
    url: https://docs.widgetic.com/resources/license
servers:
  - url: https://api.widgetic.com/v1
    description: Production server
    variables:
      env:
        default: production
        description: Environment
      apiUrl:
        default: https://api.widgetic.com
        description: API URL
      apiVersion:
        default: /v1
        description: API Version path prefix
security: []
tags: []
paths:
  /partners/{partnerId}/notifications/settings:
    put:
      tags:
        - Partners
      summary: Choose where your notifications go
      description: >
        Changes who gets the emails, which events you want by email and by
        webhook, and the address of your webhook.

        A key you leave out of the body is left as it was; send only what
        changes.


        **Email.** `emailRecipients` is the list of addresses (at most five).
        While it is empty the emails about

        invoices go to the billing emails of your billing profile (your contact
        email when there are none), and the

        others to your contact email. The events about money and about the
        standing of your account are always

        emailed, whatever `emailEvents` says; it narrows the others.


        **Webhook.** `webhookUrl` is where Widgetic sends a signed `POST` for
        each event, so that your own system

        can act on it (mark an invoice paid, warn your team that credits are
        low). The address must be `https` on the

        standard port, on a public site, and must not redirect. Setting an
        address when you have no secret yet makes

        one, and the answer carries it as `webhookSecret`: **keep it now, it is
        shown once**. `webhookEvents` narrows

        what is sent.


        Each call has a JSON body, `{ "id": "evt_...", "type": "invoice.paid",
        "createdAt": "...", "partnerId": "...",

        "data": { ... } }` (`data` is the `data` of `PartnerNotification`), and
        these headers:

        `webhook-id` (the same as `id`, and the same on every retry),
        `webhook-timestamp` (seconds since 1970) and

        `webhook-signature` (`v1,` and a base64 HMAC-SHA256). It is the Standard
        Webhooks scheme, so any of its

        libraries verifies it. By hand: take your secret without the `whsec_`
        prefix, decode it from base64, and sign

        the text `<webhook-id>.<webhook-timestamp>.<the raw body>` with it; the
        header holds `v1,<base64 of the

        result>` (two signatures separated by a space while a rotated secret
        overlaps). Reject a `webhook-timestamp`

        that is more than five minutes old.


        Answer with a 2xx status within ten seconds. Anything else is tried
        again, eight attempts in all over about

        two days (`listPartnerNotificationDeliveries` shows each). Delivery is
        at least once: if your answer was lost

        the same event arrives again with the same `id`, so drop what you have
        already handled by it.


        Changing the settings needs an API key with full access: they decide
        where your notifications go.

        The caller must be the person who administers the partner, or a Widgetic
        administrator.
      operationId: updatePartnerNotificationSettings
      parameters:
        - in: path
          name: partnerId
          required: true
          schema:
            type: string
            format: uuid
          description: The partner whose notification settings to change
        - $ref: '#/components/parameters/IdempotencyKeyOptional'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePartnerNotificationSettingsRequest'
      responses:
        '200':
          description: The settings were saved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerNotificationSettingsChangeResponse'
        '400':
          description: >-
            A value is missing, malformed or not allowed
            (INVALID_NOTIFICATION_SETTINGS). `error.details.problems` names each
            field and says why. Nothing was saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: The API key is missing or invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            The caller does not administer this partner, or the API key has not
            full access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: There is no such partner (reported to administrators only)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            Too many changes in a short time. Try again after the Retry-After
            seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Webhooks cannot be set up on this server right now
            (WEBHOOK_SIGNING_UNAVAILABLE). Nothing was changed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKeyAuth: []
      x-code-samples:
        - lang: TypeScript
          label: TypeScript SDK
          source: >
            import { Configuration, PartnersApi } from '@widgetic/api-sdk-ts';


            const partnersApi = new PartnersApi(new Configuration({ apiKey:
            'YOUR_API_KEY' }));


            // Send every payment event to your own system:

            const { data: change } = await
            partnersApi.updatePartnerNotificationSettings({
              partnerId,
              updatePartnerNotificationSettingsRequest: {
                webhookUrl: 'https://example.com/widgetic/events',
                webhookEvents: ['invoice.issued', 'invoice.paid', 'invoice.failed']
              }
            });


            // Shown once: put it in your receiver's configuration now.

            console.log(change.webhookSecret);
components:
  parameters:
    IdempotencyKeyOptional:
      in: header
      name: Idempotency-Key
      required: false
      description: >-
        Optional: without it the call is carried out every time it is sent. A
        key of your own that names this one request; a UUID is ideal. It is 8 to
        50 characters of letters, digits, `-` and `_`. Send the same key again
        when you retry (after a timeout, a dropped connection or a `5xx`) and
        the call is carried out once: the retry gets the first answer back,
        marked `X-Idempotency-Cached: true`. The same key with a different body
        is refused with `422`, and a retry that arrives while the first call is
        still running with `409` (see `Retry-After`).
      schema:
        type: string
        minLength: 8
        maxLength: 50
        pattern: ^[a-zA-Z0-9_-]{8,50}$
        example: 9b2d6f0a-3c41-4e5a-8d77-1f2e3a4b5c6d
  schemas:
    UpdatePartnerNotificationSettingsRequest:
      type: object
      description: What to change. A key you leave out is left as it was.
      properties:
        emailRecipients:
          type: array
          maxItems: 5
          description: >-
            The addresses the emails go to, at most five. An empty list goes
            back to the defaults.
          items:
            type: string
        emailEvents:
          type: array
          nullable: true
          description: The events you want by email. Null for every event.
          items:
            $ref: '#/components/schemas/PartnerNotificationEventType'
        webhookEvents:
          type: array
          nullable: true
          description: The events to send to your webhook. Null for every event.
          items:
            $ref: '#/components/schemas/PartnerNotificationEventType'
        webhookUrl:
          type: string
          nullable: true
          maxLength: 2000
          description: >-
            Where to send the signed calls. It must be an https address on the
            standard port, on a public site, and it must not redirect. Null or
            an empty text switches the webhook off. Setting an address when you
            have no secret yet makes one.
      example:
        emailRecipients: []
        emailEvents:
          - Example PartnerNotificationEventType
        webhookEvents:
          - Example PartnerNotificationEventType
        webhookUrl: Example webhookUrl
    PartnerNotificationSettingsChangeResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          description: Always `true` on a success.
          example: true
        data:
          $ref: '#/components/schemas/PartnerNotificationSettingsChange'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    ErrorResponse:
      type: object
      required:
        - success
        - message
        - error
      additionalProperties: true
      properties:
        success:
          type: boolean
          description: Always `false` on a failure.
          example: false
        message:
          type: string
          description: The same text as `error.message`, for a caller that reads one line.
        error:
          $ref: '#/components/schemas/ErrorDetail'
    PartnerNotificationEventType:
      type: string
      description: What happened. The event types you can be told about.
      enum:
        - invoice.issued
        - invoice.due_soon
        - invoice.overdue
        - invoice.paid
        - invoice.failed
        - credits.low
        - credits.managed_user_cap_reached
        - partner.activated
        - partner.paused
        - partner.resumed
        - storage.check_failed
        - composition.created
        - composition.updated
        - widget.published
        - upload.created
        - entry.created
        - workflow.created
        - workflow.published
        - workflow.state_changed
        - workflow.deleted
    PartnerNotificationSettingsChange:
      type: object
      description: >-
        The settings after a change, and the new signing secret when one was
        made.
      required:
        - settings
        - webhookSecret
      properties:
        settings:
          $ref: '#/components/schemas/PartnerNotificationSettings'
        webhookSecret:
          type: string
          nullable: true
          description: >-
            The secret that signs your webhook, in the form your receiver is
            configured with (`whsec_...`). It is in this answer ONLY: keep it
            now, it cannot be read again. Null when the change made no secret.
      example:
        settings: null
        webhookSecret: Example webhookSecret
    ResponseMeta:
      type: object
      description: >-
        Extra information about the answer: where a page sits in a list, the
        cursor of the next page, or warnings about a call that succeeded with a
        caveat.
      additionalProperties: true
      properties:
        page:
          type: integer
          description: The page that was read, counting from 1.
          example: 1
        size:
          type: integer
          description: How many items one page holds.
          example: 20
        total:
          type: integer
          description: How many items the whole list has.
          example: 135
        limit:
          type: integer
          description: The same as `size`.
          example: 20
        offset:
          type: integer
          description: How many items come before this page.
          example: 0
        hasNextPage:
          type: boolean
          example: true
        hasPreviousPage:
          type: boolean
          example: false
        nextCursor:
          type: string
          nullable: true
          description: >-
            Pass this as `cursor` to read the next page of a list that is read
            by cursor. `null` on the last page.
        warnings:
          type: array
          items:
            type: string
          description: >-
            Things the call did not do, though it succeeded (for example a table
            that could not be created just now).
    ErrorDetail:
      type: object
      required:
        - code
        - message
        - timestamp
      properties:
        code:
          type: string
          description: Machine-readable error code.
          example: RESOURCE_NOT_FOUND
        message:
          type: string
          description: Human-readable explanation.
          example: Composition not found
        param:
          type: string
          description: The field that caused the error, when one did.
          example: name
        docUrl:
          type: string
          description: Where this error is explained.
        suggestedAction:
          type: string
          description: What to do about it.
        retryAfter:
          type: integer
          description: >-
            Seconds to wait before trying again (rate limits). The same number
            is in the `Retry-After` header.
          example: 60
        details:
          type: object
          additionalProperties: true
          description: >-
            More about the error: the fields that failed, a limit that was
            reached.
        correlationId:
          type: string
          description: Quote this when you ask support about the call.
          example: req_123e4567-e89b-12d3-a456-426614174000
        timestamp:
          type: string
          format: date-time
          example: '2026-10-15T10:00:00.000Z'
    PartnerNotificationSettings:
      type: object
      description: >-
        Where your notifications go. The secret that signs your webhook is never
        part of it.
      required:
        - partnerId
        - emailRecipients
        - defaultEmailRecipients
        - emailEvents
        - webhookUrl
        - webhookEvents
        - webhookSecretSet
        - webhookSecretRotatedAt
        - webhookSigningAvailable
        - events
      properties:
        partnerId:
          type: string
          format: uuid
        emailRecipients:
          type: array
          description: The addresses the emails go to. Empty means the defaults.
          items:
            type: string
        defaultEmailRecipients:
          $ref: '#/components/schemas/PartnerNotificationDefaultRecipients'
        emailEvents:
          type: array
          nullable: true
          description: >-
            The events you want by email. Null means every event. The events
            marked `alwaysEmailed` are emailed whatever it says.
          items:
            $ref: '#/components/schemas/PartnerNotificationEventType'
        webhookUrl:
          type: string
          nullable: true
          description: >-
            Where Widgetic sends a signed call for each event. Null while the
            webhook is switched off.
        webhookEvents:
          type: array
          nullable: true
          description: The events sent to your webhook. Null means every event.
          items:
            $ref: '#/components/schemas/PartnerNotificationEventType'
        webhookSecretSet:
          type: boolean
          description: Whether a signing secret exists. Calls are made only when it does.
        webhookSecretRotatedAt:
          type: string
          format: date-time
          nullable: true
          description: When the current secret was made
        webhookSigningAvailable:
          type: boolean
          description: >-
            False when this server cannot sign webhooks, in which case a webhook
            cannot be set up yet
        events:
          type: array
          description: Every event there is, for a settings screen to list
          items:
            $ref: '#/components/schemas/PartnerNotificationEvent'
      example:
        partnerId: 3fa85f64-5717-4562-b3fc-2c963f66afa6
        emailRecipients: []
        defaultEmailRecipients: null
        emailEvents:
          - Example PartnerNotificationEventType
        webhookUrl: Example webhookUrl
        webhookEvents:
          - Example PartnerNotificationEventType
        webhookSecretSet: true
        webhookSecretRotatedAt: '2026-01-15T09:30:00.000Z'
        webhookSigningAvailable: true
        events:
          - Example PartnerNotificationEvent
    PartnerNotificationDefaultRecipients:
      type: object
      description: Who gets the emails while you have given no addresses of your own.
      required:
        - payments
        - other
      properties:
        payments:
          type: array
          description: >-
            For the invoice events, the billing emails of your billing profile,
            or your contact email when there are none
          items:
            type: string
        other:
          type: array
          description: For every other event, your contact email
          items:
            type: string
      example:
        payments: []
        other: []
    PartnerNotificationEvent:
      type: object
      description: One kind of event you can be told about.
      required:
        - type
        - group
        - label
        - description
        - alwaysEmailed
        - delivery
      properties:
        type:
          $ref: '#/components/schemas/PartnerNotificationEventType'
        group:
          type: string
          enum:
            - payments
            - credits
            - account
            - storage
            - content
        label:
          type: string
        description:
          type: string
          description: One sentence that says when it happens
        alwaysEmailed:
          type: boolean
          description: >-
            True for money and standing: you are emailed whatever you chose, and
            can narrow only what your own system receives.
        delivery:
          type: string
          enum:
            - all
            - webhook
          description: >-
            `all`: email (when chosen), dashboard inbox and webhook. `webhook`:
            signed call only — no email and not listed in the dashboard inbox.
      example:
        type: null
        group: Example group
        label: Example label
        description: Example description
        alwaysEmailed: true
        delivery: Example delivery
  securitySchemes:
    apiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

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