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

# Update your webhook URLs

> Points the webhooks on the API key used for this request somewhere new. rampWebhookURL receives onramp and offramp order updates; paymentWebhookURL receives settled payments. Only the fields you send are changed, and sending one as an empty string clears it, stopping those deliveries. The full configuration after the change is returned.

Points the webhooks on your API key somewhere new, without going through the
dashboard. Whichever key you send in `x-api-key` is the key that changes — there
is no id in the path, so a key can only ever reconfigure itself.

## The two webhooks

* **`rampWebhookURL`** — onramp and offramp order updates, posted at every status
  transition. It is the default for every order opened with this key: an order
  that sets its own `webhookURL` is announced there instead, and one that
  leaves it out is announced here.
* **`paymentWebhookURL`** — [payment](/api-reference/create-payment) settlements.

Send either, or both. A field you leave out is left exactly as it was, so moving
one webhook never disturbs the other. The response is the full configuration
after the change, both fields included, so you can confirm what the key now
holds without a second call.

## Your signing secret

The response also carries `webhookSecret` — the secret every delivery to these
URLs is signed with, so your handler can tell a real delivery from anything else
that finds the URL. It is the same secret each time; changing a URL does not
change it.

Verifying is a few lines, and [Webhook
signatures](/concepts/webhook-signatures) covers it in full. If you are moving a
webhook to a new endpoint, that is the moment to add verification to it.

## Turning a webhook off

Send the field as an empty string:

```json theme={null}
{ "paymentWebhookURL": "" }
```

The URL is removed and those deliveries stop; the key keeps working for
everything else. This is the only way to clear one — omitting the field means
"leave it alone", not "remove it".

Anything else has to be a valid absolute URL, or the request is a `400` and
nothing changes. A body naming neither field is also a `400` rather than a
silent no-op, since it usually means a misspelled field name.

## After changing it

A new `paymentWebhookURL` takes effect immediately, including for payments
already in flight — a payment opened a minute ago will settle to whatever
`paymentWebhookURL` says at the moment it settles, not what it said when it was
created.

`rampWebhookURL` works differently. An order that did not name its own webhook
takes the key's `rampWebhookURL` when it is **created**, and keeps it. Changing
the URL covers every order you open from then on; orders already open keep
reporting to the URL they started with.

Worth pairing with [Test your webhook](/api-reference/test-webhook): change the
URL, then fire a sample payload at it and confirm your new endpoint answers `2xx`
before you rely on it.

One thing to check when moving a URL: redirects are not followed, so a delivery
to a URL that redirects — `http` to `https`, or a bare domain to `www` — counts
as failed. Point the webhook at the final destination.


## OpenAPI

````yaml PATCH /pub/v2/webhook
openapi: 3.0.0
info:
  title: Paj Public API
  description: >-
    Programmatic access to Paj's on/off ramp. Register a Nigerian bank account,
    get

    the on-chain address that pays it, create offramp orders for a specific
    amount,

    and read the live conversion rates.


    Every request must carry an `x-api-key` header. Keys are scoped to a
    business,

    and the rates you receive already have that business's fee applied.
  version: 2.0.0
  contact: {}
servers:
  - url: https://api.paj.cash
    description: Production
security: []
tags: []
paths:
  /pub/v2/webhook:
    patch:
      tags:
        - Pub V2
      summary: Update your webhook URLs
      description: >-
        Points the webhooks on the API key used for this request somewhere new.
        rampWebhookURL receives onramp and offramp order updates;
        paymentWebhookURL receives settled payments. Only the fields you send
        are changed, and sending one as an empty string clears it, stopping
        those deliveries. The full configuration after the change is returned.
      operationId: PubV2Controller_updateWebhooks
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookDto'
      responses:
        '200':
          description: The webhook configuration now on the key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookConfigDto'
        '400':
          description: Neither URL was provided, or one of them is not a valid URL
        '401':
          description: Missing or invalid API key (x-api-key header)
      security:
        - x-api-key: []
components:
  schemas:
    UpdateWebhookDto:
      type: object
      properties:
        rampWebhookURL:
          type: string
          description: >-
            Where onramp and offramp order updates are posted. Send an empty
            string to stop receiving them.
          example: https://example.com/webhook
        paymentWebhookURL:
          type: string
          description: >-
            Where settled payments are posted. Send an empty string to stop
            receiving them.
          example: https://example.com/payment-webhook
    WebhookConfigDto:
      type: object
      properties:
        rampWebhookURL:
          type: string
          description: Where onramp and offramp order updates are posted.
          example: https://example.com/webhook
        paymentWebhookURL:
          type: string
          description: Where settled payments are posted.
          example: https://example.com/payment-webhook
        webhookSecret:
          type: string
          description: >-
            The secret every delivery to these URLs is signed with. Verify a
            delivery by computing HMAC-SHA256 over `{X-PAJ-Timestamp}.{raw
            body}` with this secret and comparing it, in constant time, against
            the hex digest in X-PAJ-Signature (after the `v1=` prefix). Reject
            deliveries whose timestamp is more than a few minutes old.
          example: whsec_2f1c…
  securitySchemes:
    x-api-key:
      type: apiKey
      in: header
      name: x-api-key

````

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