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

# Register a notification webhook (free)

> Registers (or replaces) an HTTPS webhook URL to receive the calling wallet's account notifications as signed POSTs — banking application status changes, bank transfer and payout completions, agent wallet deposits, card orders, and every other event the user is notified about. This closes the polling gap for agents: instead of re-fetching status endpoints, point this at any URL you can receive HTTP on (your harness's inbound webhook endpoint, or a relay you poll).

Deliveries are signed per the Standard Webhooks specification (https://www.standardwebhooks.com/): each POST carries `webhook-id`, `webhook-timestamp`, and `webhook-signature` (`v1,<base64 HMAC-SHA256>`) headers verifiable with any standard-webhooks library using the returned `secret`. The body is `{"type": "notification.<category>", "timestamp": "<ISO 8601>", "data": {"user_id", "title", "text", "category"}}`.

The `secret` is returned exactly once, by this call. Re-registering rotates the secret, replaces the URL, and re-enables a registration that was auto-disabled after 50 consecutive failed deliveries. Registering also notifies the account owner through their other channels and fires a first signed test delivery (`type` `notification.account`) at the new URL.

Deliveries time out after 10 seconds and are not retried; treat the webhook as a low-latency hint and the status endpoints as the source of truth. The URL must be public HTTPS.

Requires a Bearer token from `/auth` or `/get-card`.



## OpenAPI

````yaml /api-reference/openapi.json post /register-webhook
openapi: 3.1.0
info:
  title: Laso Finance x402 API
  version: 1.0.0
  x-docs-revision: 63bdfe2f5409
  x-docs-manifest: https://laso.finance/.well-known/docs-version.json
  contact:
    email: agents+support@laso.finance
  x-guidance: >-
    Laso Finance is a payment-gated (x402) API that lets an AI agent spend USDC
    on real-world financial products: prepaid cards (U.S. and international),
    gift cards, push-to-card transfers to USD/EUR/GBP debit cards, and
    Venmo/PayPal payouts.


    Payment: every paid route is an x402 v2 endpoint. Call it with no payment
    header to receive a 402 challenge listing the accepted networks, then replay
    with a signed USDC payment. Both Base (eip155:8453) and Solana
    (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) are accepted on every paid route;
    the caller picks either chain.


    Identity: `GET /auth` is free and identity-only. Prove wallet ownership with
    a `SIGN-IN-WITH-X` (CAIP-122) header to receive a Firebase id_token, then
    send that token as a Bearer credential to the authenticated read routes
    (`get-card-data`, `get-account-balance`, `get-kyc-status`, etc.). Paid
    routes also return fresh auth credentials in their response, so a payment is
    never required just to obtain a token.


    Recommended flow: (1) `GET /auth` to establish identity, (2) call a paid
    route (e.g. `GET /get-card`) to purchase a product, paying USDC on Base or
    Solana, (3) poll the authenticated read routes with the returned Bearer
    token to fetch the resulting card/transfer details. Full machine-readable
    instructions live at https://laso.finance/SKILL.md.
  description: >-
    Payment-gated API for Laso Finance. All paywalled routes use the x402
    protocol — the caller includes a USDC payment header on Base (eip155:8453)
    or Solana (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) and the server verifies
    payment before processing. Free routes require no payment header.


    ## Getting started


    To set up a wallet for making x402 payments, choose a provider:


    - **Locus** (default): https://paywithlocus.com/SKILL.md

    - **Sponge**: https://wallet.paysponge.com/skill.md — automatic x402 service
    discovery

    - **Ampersend**: https://www.ampersend.ai/getting-started.md — self-custody
    on Base or Solana with dual-approval spending limits. Laso Finance is a
    default skill, so no manual endpoint registration is needed.


    ## How x402 works


    1. Call a paywalled endpoint without a payment header → receive a `402
    Payment Required` response containing payment details (price, recipient
    address, network).

    2. Construct an x402 payment header using the details from the 402 response.

    3. Replay the request with the payment header → the server verifies payment
    and processes the request.


    ## Authentication flow


    `GET /auth` is free: callers prove wallet ownership by sending a
    `SIGN-IN-WITH-X` header (CAIP-122 wallet signature). Paywalled routes
    (`/get-card`, `/order-gift-card`, `/get-push-to-card`, `/order-intl-card`)
    also return fresh auth credentials in their responses, so a payment is never
    required just to obtain a token.


    Most routes return auth credentials (`id_token`, `refresh_token`,
    `expires_in`). Use the `id_token` as a Bearer token to call authenticated
    Laso Finance endpoints like `/get-card-data`. When the `id_token` expires,
    use `POST /auth` with `grant_type: refresh_token` to get a new one.


    ## Important notes


    The `/get-card` USA prepaid card endpoint is U.S. only — issued in USD,
    usable at U.S.-based merchants only, and physical goods must ship to a U.S.
    address. For non-U.S. merchants or non-USD currencies, use `GET
    /order-intl-card` instead (international prepaid card, admin-fulfilled
    within 24 hours). All cards are intended for the caller's own use.


    For step-by-step instructions, read https://laso.finance/SKILL.md
servers:
  - url: https://laso.finance
    description: Production
security: []
paths:
  /register-webhook:
    post:
      tags:
        - Notifications
      summary: Register a notification webhook (free)
      description: >-
        Registers (or replaces) an HTTPS webhook URL to receive the calling
        wallet's account notifications as signed POSTs — banking application
        status changes, bank transfer and payout completions, agent wallet
        deposits, card orders, and every other event the user is notified about.
        This closes the polling gap for agents: instead of re-fetching status
        endpoints, point this at any URL you can receive HTTP on (your harness's
        inbound webhook endpoint, or a relay you poll).


        Deliveries are signed per the Standard Webhooks specification
        (https://www.standardwebhooks.com/): each POST carries `webhook-id`,
        `webhook-timestamp`, and `webhook-signature` (`v1,<base64 HMAC-SHA256>`)
        headers verifiable with any standard-webhooks library using the returned
        `secret`. The body is `{"type": "notification.<category>", "timestamp":
        "<ISO 8601>", "data": {"user_id", "title", "text", "category"}}`.


        The `secret` is returned exactly once, by this call. Re-registering
        rotates the secret, replaces the URL, and re-enables a registration that
        was auto-disabled after 50 consecutive failed deliveries. Registering
        also notifies the account owner through their other channels and fires a
        first signed test delivery (`type` `notification.account`) at the new
        URL.


        Deliveries time out after 10 seconds and are not retried; treat the
        webhook as a low-latency hint and the status endpoints as the source of
        truth. The URL must be public HTTPS.


        Requires a Bearer token from `/auth` or `/get-card`.
      operationId: registerWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                url:
                  type: string
                  description: >-
                    Public HTTPS URL to receive signed notification POSTs. Max
                    512 characters. Private/internal hosts are rejected.
      responses:
        '200':
          description: Webhook registered
          content:
            application/json:
              schema:
                type: object
                properties:
                  registered:
                    type: boolean
                  url:
                    type: string
                  secret:
                    type: string
                    description: >-
                      Standard Webhooks signing secret (`whsec_...`). Shown only
                      in this response — store it now. Rotate by re-registering.
                  signing:
                    type: string
                    description: Always `standard-webhooks`.
              example:
                registered: true
                url: https://agent.example.com/hooks/laso
                secret: whsec_wJalrXUtnFEMI/K7MDENGbPxRfiCY
                signing: standard-webhooks
        '400':
          description: >-
            Missing or invalid `url` (not HTTPS, not public, too long, or
            malformed)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: url must use https
        '401':
          description: Missing or invalid Bearer token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Invalid or expired token
        '403':
          description: >-
            Account is frozen. The response includes a `frozen_message` field
            explaining why.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrozenError'
      security:
        - BearerAuth: []
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
    FrozenError:
      type: object
      properties:
        error:
          type: string
          example: Account is frozen
        frozen_message:
          type: string
          description: Human-readable explanation of why the account is frozen
  securitySchemes:
    BearerAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Firebase ID token from `/auth` or any paid route, sent as a Bearer
        token: `Authorization: Bearer <id_token>` (the `Bearer ` prefix is
        required).

````