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

# POST /v1/webhooks — Register a Webhook Endpoint

> Register an HTTPS endpoint to receive signed order updates. Returns the signing secret once.

Registers an endpoint and returns its signing `secret` — **once**. There is no endpoint that reads it back; if you lose it, rotate.

The URL must be publicly routable HTTPS. Anything resolving to a private, loopback, link-local or CGNAT address is rejected here and re-checked before every send, because DNS can be re-pointed after registration. Maximum 5 endpoints per account.

Verify the signature as shown in the [Webhooks guide](/guides/webhooks).

**Authentication required.** Send your key as `Authorization: Bearer csb_pub_...`. A read key is enough — managing webhooks moves no money.


## OpenAPI

````yaml POST /webhooks
openapi: 3.1.0
info:
  title: CSBoard API
  version: 1.0.0
  description: >-
    Market data over the CSBoard marketplace — live listings, floats, stickers,
    minAsk prices, FX rates — plus opt-in buying straight from your balance.
    Free to read, key-gated, built for automation.
  contact:
    name: CSBoard
    url: https://csboard.com/docs
servers:
  - url: https://csboard.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Status
    description: Liveness and freshness probes.
  - name: Market data
    description: Read the live catalog, prices, and FX rates.
  - name: Trading
    description: Buy listings from your CSBoard balance. Opt-in, key-gated.
  - name: Account
    description: Your balance, settled funds, and trading status.
  - name: Webhooks
    description: Register an endpoint and receive signed order updates instead of polling.
paths:
  /webhooks:
    post:
      tags:
        - Webhooks
      summary: Register a webhook endpoint
      description: >-
        Register an HTTPS endpoint. The response carries the signing `secret`
        ONCE — there is no endpoint that returns it again, only `rotate-secret`.
        Maximum 5 endpoints per account. The URL must be publicly routable:
        anything resolving to a private, loopback, link-local or CGNAT address
        is rejected, and re-checked before every send because DNS can be
        re-pointed after registration.
      operationId: createWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                url:
                  type: string
                  format: uri
                  description: Public HTTPS endpoint that will receive POSTs.
                events:
                  type: array
                  items:
                    type: string
                    enum:
                      - order.updated
                      - webhook.test
                  description: Omit or leave empty to receive every event type.
                description:
                  type: string
                  maxLength: 200
                  description: Your own label, e.g. `prod` or `staging`.
      responses:
        '201':
          description: Created. `secret` is shown only here.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    allOf:
                      - type: object
                        properties:
                          id:
                            type: string
                          url:
                            type: string
                            format: uri
                          events:
                            type: array
                            items:
                              type: string
                              enum:
                                - order.updated
                                - webhook.test
                            description: >-
                              Subscribed event types. An empty request value
                              means all of them; the response always lists them
                              explicitly.
                          enabled:
                            type: boolean
                          description:
                            type: string
                            nullable: true
                          last_success_at:
                            type: string
                            format: date-time
                            nullable: true
                          last_failure_at:
                            type: string
                            format: date-time
                            nullable: true
                          last_error:
                            type: string
                            nullable: true
                            description: >-
                              Verbatim reason the last attempt failed — HTTP
                              status, timeout, or URL rejection.
                          consecutive_failures:
                            type: integer
                            description: >-
                              Reset on any success. At 50 the endpoint is
                              auto-disabled.
                          created_at:
                            type: string
                            format: date-time
                      - type: object
                        properties:
                          secret:
                            type: string
                            description: HMAC signing secret, `csb_whsec_…`. Shown once.
        '400':
          description: >-
            `invalid_webhook_url` — not https, embeds credentials, or resolves
            to a private address.
        '409':
          description: '`too_many_webhooks` — 5 endpoints already registered.'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Send your key as a Bearer token on every request: `Authorization: Bearer
        csb_pub_...`. Generate keys in your CSBoard profile.

````