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

# Every bridge's health over 24 hours

> The HOT bridge's deposits and withdrawals by chain over a 24-hour window, both kit's direct transfers and 1Click's legs over the HOT bridge (referral `intents.tg`): what finished and how long it took (p50, p90), what is in flight, stuck, in the old backlog or refund-only, what failed, an hourly trend, and the stuck and failed transfers themselves. Feeds HEX's `/bridges` page.

What is in flight is split by what it needs (`triage`): the live flow (in flight for less than the window; `stuck` past `stuck_after_s`), the **backlog** (in flight longer than the window, still payable) and **refund**-only withdrawals that no payout can land (to the token contract, to the zero address, Stellar nonces past 60 days). A chain's `health` is the live flow's. A chain with `error_kind: "read"` has its withdrawals in flight unknown, not zero. Without the database it answers an empty picture.



## OpenAPI

````yaml https://mpc.hex-api.app/openapi.json get /bridge/monitor
openapi: 3.1.0
info:
  title: HEX MPC API
  version: 1.0.0
  summary: HOT bridge signatures and relay, the bridge registry and monitor.
  description: >
    The public API of `hex-mpc`, a Cloudflare Worker in front of the HOT MPC
    nodes. It replaces the old HOT backend's bridge endpoints

    (`api0.herewallet.app`: `process_bridge_deposit`, `auto_deposit_register`,
    ...) and HOR (`rpc1.hotdao.ai`, `rpc2.hotdao.ai`).


    ## Which routes to use


    - **Credit a deposit to NEAR Intents**: `POST /relay/deposit` with the
    source tx (or the deposit's fields). The service reads the deposit on its
    chain, signs it and sends `mt_deposit_call` on NEAR, paying the gas. This is
    what `process_bridge_deposit` did.

    - **Pay out withdrawals**: `POST /relay/withdraw` with the chain and the
    receiver; poll `GET /relay/jobs/{chain}/{id}`.

    - **Clear a paid withdrawal**: `POST /relay/clear`.

    - **Submit transactions yourself**: the `Signatures` routes return the MPC
    signatures only.

    - **Record what your users do** (optional, for support and recovery): `POST
    /bridge/register`, `/bridge/deposits`, `/bridge/withdrawals`.


    Every relay call sends only what holds on chain (a deposit that happened,
    the payout of a withdrawal omni holds, the clear of a paid one), and each at
    most once, so retrying a call is safe.


    ## Conventions


    - **Bodies** are JSON objects, at most 32 KiB (`/intents/solver`: 128 KiB).
    A body that is not a JSON object is a `422`, a larger one a `413`.

    - **Big integers.** Nonces and amounts are answered as decimal strings. In
    requests they may be decimal strings or JSON integers: integers above 2^53
    are read exactly (the bridge's nonces are about 1.8e21), but a decimal
    string is the safer choice for clients whose JSON encoder uses doubles.

    - **Nonces** are omni's: `unix seconds * 10^12 + n`.

    - **Encodings.** omni's token ids, receivers and the bridge signatures are
    base58; NEAR tx hashes are base58.

    - **Chain ids.** Chain ids are omni's (`v2_1.omni.hot.tg`), not always the
    chain's own: EVM chains use their EIP-155 id (Ethereum 1, Optimism 10, BNB
    56, Polygon 137, Monad 143, X Layer 196, Base 8453, Arbitrum 42161,
    Avalanche 43114, ...); the others have omni's numbers: Solana 1001, NEAR
    1010, Stellar 1100, TON 1117 (TON v1, 1111, is dead), Juno 4444118, Gonka
    4444119.

    - **Errors** are `{ "detail": "..." }` with an HTTP status (FastAPI's
    format, kept from HOR), the router's own `404`, `405` and `429` included.
    Clients should branch on the status and show or log the `detail`. A `5xx`
    (and a `502`/`503` in particular) is worth retrying with backoff; a `4xx`
    will answer the same until something changes on chain.

    - **CORS.** Any origin; the request's `Origin` is echoed with
    `access-control-allow-credentials: true`, and preflights allow `GET, POST,
    OPTIONS` with any header.

    - **Times** in answers are milliseconds since the epoch unless named `*_s`
    (seconds).


    ## Rate limits


    Per client IP (an IPv6 client by its /64), over 60 seconds, counted per
    Cloudflare location:


    | Class | Limit | Routes |

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

    | `bridge` | 300 / 60 s | `/withdraw/sign`, `/deposit/sign`, `/clear/sign`,
    `/relay/*`, `/bridge/*` |

    | `solver` | 120 / 60 s | `/intents/solver` |


    `/v1/health`, `/v1/time` and `/openapi.json` are not limited. Over the limit
    the answer is `429` `{ "detail": "Too many requests" }` with `Retry-After:
    60`.


    ## Load protection


    The MPC nodes are a fixed quorum: every signature is a round on each of
    them. So on top of the per-IP limits, every call that reaches the nodes (the
    `Signatures` routes, and the relay's own signing) is admitted globally,
    whoever asks:


    - **Rate per kind of signing**, by default 300 a minute each for
    withdrawals, deposits and clears: over it, `429` with `Retry-After`.

    - **Signings at once**, 60 in all, each kind its own share: over it, `503`
    `MPC nodes are busy, try again shortly` with `Retry-After`. Also `503` with
    `Retry-After` when the nodes answer `429` or too few of them are up.

    - **One signing per message.** A signature is kept for a day and answered
    again (a retry, another client, the relay), and while it is being made a
    second request waits for it (or gets `503` `This signature is being made,
    try again shortly` after 45 s). A refusal of the bridge (`400`) is answered
    again for 5 seconds.

    - **Refusals before the nodes**: a deposit omni already credited (`400`
    `Deposit … is already credited`), a withdrawal no payout can land (`400`
    `Withdrawal … : it can only be refunded`: it pays the token contract itself,
    the zero address, or a Stellar nonce past its 60 days).


    Retry a `429` or `503` after its `Retry-After`.
servers:
  - url: https://mpc.hex-api.app
    description: Production
security: []
tags:
  - name: Relay
    description: >-
      The recommended integration: the service sends the bridge's transactions
      and pays for them. Deposits are credited to NEAR Intents; withdrawals are
      paid out on their chain and cleared on omni.
  - name: Signatures
    description: >-
      The bridge's MPC signatures, for callers that submit the transactions
      themselves (HOR-compatible: same bodies, answers and errors). Each
      signature needs omni's word, and a deposit or clear also its AuthCall on
      chain, so a caller cannot forge or redirect one.
  - name: Registry
    description: >-
      The bridge registry: what users do on the bridge, as clients report it and
      as the relay sees it on chain. A post only records a claim: nothing is
      signed or sent for it, and what the relay reads on chain overrides it.
      Lookups answer 503 while the registry's database is not configured.
  - name: Monitor
    description: Health of every bridge HEX moves funds through, over 24 hours.
  - name: Intents
    description: >-
      NEAR Intents solver relay passthrough, used by HEX/HOT kit to publish
      signed intents.
  - name: Service
    description: Health, time and this document.
paths:
  /bridge/monitor:
    get:
      tags:
        - Monitor
      summary: Every bridge's health over 24 hours
      description: >-
        The HOT bridge's deposits and withdrawals by chain over a 24-hour
        window, both kit's direct transfers and 1Click's legs over the HOT
        bridge (referral `intents.tg`): what finished and how long it took (p50,
        p90), what is in flight, stuck, in the old backlog or refund-only, what
        failed, an hourly trend, and the stuck and failed transfers themselves.
        Feeds HEX's `/bridges` page.


        What is in flight is split by what it needs (`triage`): the live flow
        (in flight for less than the window; `stuck` past `stuck_after_s`), the
        **backlog** (in flight longer than the window, still payable) and
        **refund**-only withdrawals that no payout can land (to the token
        contract, to the zero address, Stellar nonces past 60 days). A chain's
        `health` is the live flow's. A chain with `error_kind: "read"` has its
        withdrawals in flight unknown, not zero. Without the database it answers
        an empty picture.
      operationId: getBridgeMonitor
      responses:
        '200':
          description: The monitor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MonitorResponse'
              examples:
                example:
                  summary: One chain
                  value:
                    now: 1792944180000
                    window_s: 86400
                    stuck_after_s:
                      deposit: 900
                      withdrawal: 600
                    backlog_after_s: 86400
                    sources:
                      hot_sweep: 1792944150000
                      oneclick: 1792944160000
                      oneclick_enabled: true
                    totals:
                      deposit:
                        done: 42
                        oneclick: 30
                        usd: 18250.4
                        pending: 1
                        stuck: 0
                        backlog: 0
                        refund: 0
                        failed: 0
                        p50_s: 95
                        p90_s: 240
                        samples: 38
                        oldest_s: 60
                      withdrawal:
                        done: 17
                        oneclick: 9
                        usd: 6100
                        pending: 2
                        stuck: 1
                        backlog: 0
                        refund: 0
                        failed: 0
                        p50_s: 120
                        p90_s: 600
                        samples: 15
                        oldest_s: 900
                    chains:
                      - chain: '1100'
                        name: Stellar
                        deposit:
                          done: 42
                          oneclick: 30
                          usd: 18250.4
                          pending: 1
                          stuck: 0
                          backlog: 0
                          refund: 0
                          failed: 0
                          p50_s: 95
                          p90_s: 240
                          samples: 38
                          oldest_s: 60
                        withdrawal:
                          done: 17
                          oneclick: 9
                          usd: 6100
                          pending: 2
                          stuck: 1
                          backlog: 0
                          refund: 0
                          failed: 0
                          p50_s: 120
                          p90_s: 600
                          samples: 15
                          oldest_s: 900
                        health: slow
                    items:
                      - source: hot
                        direction: withdrawal
                        chain: '1100'
                        id: '1792944123000000004211'
                        state: pending
                        triage: stuck
                        status: running
                        created_at: 1792943280000
                        age_s: 900
                        amount: 2.5 USDC
                        receiver: >-
                          GDJ4JZXZELZD737NVFORH4PSSQDWFDZTKW3AIDKHYQG23ZXBPDGGQBJK
                        txs:
                          - kind: near
                            hash: 2rQmS4n4TxT7GJ26XLDDZEHEmsizLb1ezGC81zr8dpkR
                            url: >-
                              https://nearblocks.io/txns/2rQmS4n4TxT7GJ26XLDDZEHEmsizLb1ezGC81zr8dpkR
                        detail: >-
                          payment of 1792944123000000004211 is not at latest - 1
                          yet
                    series:
                      - t: 1792940580000
                        deposit:
                          done: 3
                          oneclick: 2
                          failed: 0
                          p50_s: 90
                          usd: 1200
                        withdrawal:
                          done: 1
                          oneclick: 0
                          failed: 0
                          p50_s: 130
                          usd: null
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    MonitorResponse:
      type: object
      required:
        - now
        - window_s
        - stuck_after_s
        - backlog_after_s
        - sources
        - totals
        - chains
        - items
        - series
      properties:
        now:
          type: integer
          description: When this answer was built, ms.
        window_s:
          type: integer
          description: The statistics' window (24 h), s.
        stuck_after_s:
          type: object
          required:
            - deposit
            - withdrawal
          properties:
            deposit:
              type: integer
            withdrawal:
              type: integer
          description: In flight longer than this is stuck, s.
        backlog_after_s:
          type: integer
          description: In flight longer than this is backlog, s.
        sources:
          type: object
          required:
            - hot_sweep
            - oneclick
            - oneclick_enabled
          description: When each source was last read (ms; null when never).
          properties:
            hot_sweep:
              type:
                - integer
                - 'null'
            oneclick:
              type:
                - integer
                - 'null'
            oneclick_enabled:
              type: boolean
        totals:
          type: object
          required:
            - deposit
            - withdrawal
          properties:
            deposit:
              $ref: '#/components/schemas/FlowStats'
            withdrawal:
              $ref: '#/components/schemas/FlowStats'
        chains:
          type: array
          items:
            $ref: '#/components/schemas/MonitorChain'
        items:
          type: array
          items:
            $ref: '#/components/schemas/MonitorItem'
          description: >-
            Stuck, failed, refund and backlog transfers in that order, oldest
            first, at most 100 of each.
        series:
          type: array
          items:
            $ref: '#/components/schemas/MonitorBucket'
          description: The window by the hour, oldest first.
    FlowStats:
      type: object
      description: A chain's deposits or withdrawals over the window.
      required:
        - done
        - oneclick
        - refuel
        - usd
        - pending
        - stuck
        - backlog
        - refund
        - failed
        - p50_s
        - p90_s
        - samples
        - oldest_s
      properties:
        done:
          type: integer
          description: Finished in the window.
        oneclick:
          type: integer
          description: Of them, 1Click's deposit legs.
        refuel:
          type: integer
          description: >-
            Of them, bridge-refuel's withdrawals of HOT wallet users (as the
            refuel sweep saw omni let them go); the rest are kit's direct ones.
        usd:
          type:
            - number
            - 'null'
          description: USD moved, where priced (1Click's legs); null with none priced.
        pending:
          type: integer
          description: In flight for less than the window (the live flow).
        stuck:
          type: integer
          description: Of them, past `stuck_after_s`.
        backlog:
          type: integer
          description: In flight longer than the window, still payable.
        refund:
          type: integer
          description: 'In flight and never payable: refund only.'
        failed:
          type: integer
          description: Refunded or failed in the window.
        p50_s:
          type:
            - number
            - 'null'
          description: Median duration of the finished ones, s.
        p90_s:
          type:
            - number
            - 'null'
          description: 90th percentile, s.
        samples:
          type: integer
          description: How many durations the percentiles stand on.
        oldest_s:
          type:
            - number
            - 'null'
          description: The oldest live in-flight one's age, s.
    MonitorChain:
      type: object
      required:
        - chain
        - name
        - deposit
        - withdrawal
        - health
      properties:
        chain:
          type: string
          description: omni's chain id.
          examples:
            - '1100'
        name:
          type: string
          examples:
            - Stellar
        deposit:
          $ref: '#/components/schemas/FlowStats'
        withdrawal:
          $ref: '#/components/schemas/FlowStats'
        health:
          type: string
          enum:
            - ok
            - slow
            - down
          description: >-
            The live flow's: `slow` when something is stuck, `down` when stuck
            and nothing of that way finished in the window.
        error:
          type: string
          description: Why the chain is not read, or what went wrong on it.
        error_kind:
          type: string
          enum:
            - read
            - relay
          description: >-
            `read`: its pending withdrawals could not be read (unknown, not
            zero). `relay`: read, but the relay could not act on them.
    MonitorItem:
      type: object
      description: >-
        A transfer in flight past its stuck threshold, in the backlog,
        refund-only, or failed in the window.
      required:
        - source
        - direction
        - chain
        - id
        - state
        - status
        - created_at
        - age_s
      properties:
        source:
          type: string
          enum:
            - hot
            - oneclick
          description: Seen by the relay (omni, the registry), or in 1Click Explorer.
        direction:
          type: string
          enum:
            - deposit
            - withdrawal
        chain:
          type: string
          description: omni's chain id.
        id:
          type: string
          description: >-
            omni's nonce (a withdrawal), the source tx (a direct deposit), or
            1Click's deposit address (and memo) and leg.
        state:
          type: string
          enum:
            - pending
            - incomplete
            - refunded
            - failed
          description: '`incomplete`: 1Click got less than quoted.'
        triage:
          type: string
          enum:
            - stuck
            - failed
            - backlog
            - refund
          description: What it needs.
        reason:
          type: string
          description: 'Why it can only be refunded (`triage: refund`).'
        status:
          type: string
          description: >-
            1Click's status, or the registry's / the relay's (`registered`,
            `queued`, `active`, `cooldown`, ...).
        created_at:
          type: integer
          description: ms.
        age_s:
          type: number
        amount:
          type: string
          description: Readable (`12.5 BNB`), or the raw amount and token id.
        amount_usd:
          type: number
        receiver:
          type: string
          description: >-
            The target chain's receiver (withdrawal) or the intents account
            (deposit).
        txs:
          type: array
          items:
            $ref: '#/components/schemas/MonitorTx'
        detail:
          type: string
          description: The relay's or 1Click's last word on it.
    MonitorBucket:
      type: object
      description: 'One hour of the window: what finished in it.'
      required:
        - t
        - deposit
        - withdrawal
      properties:
        t:
          type: integer
          description: The hour's start, ms.
        deposit:
          $ref: '#/components/schemas/BucketFlow'
        withdrawal:
          $ref: '#/components/schemas/BucketFlow'
    Error:
      type: object
      description: 'Every error: FastAPI''s `{ detail }` with the HTTP status.'
      required:
        - detail
      properties:
        detail:
          type: string
          description: What went wrong, readable.
      examples:
        - detail: Nonce was not used on target chain
    MonitorTx:
      type: object
      required:
        - kind
        - hash
      properties:
        kind:
          type: string
          enum:
            - source
            - near
            - target
        hash:
          type: string
        url:
          type: string
          format: uri
    BucketFlow:
      type: object
      required:
        - done
        - oneclick
        - refuel
        - failed
        - p50_s
        - usd
      properties:
        done:
          type: integer
        oneclick:
          type: integer
        refuel:
          type: integer
        failed:
          type: integer
        p50_s:
          type:
            - number
            - 'null'
        usd:
          type:
            - number
            - 'null'
  responses:
    TooManyRequests:
      description: >-
        Over the route's per-IP rate limit (60 s), or, on a route that signs,
        over the MPC nodes' signing rate (see Load protection). Wait
        `Retry-After` seconds.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            limited:
              value:
                detail: Too many requests
            signing:
              value:
                detail: Too many bridge_deposit signings, try again in 1 s
    InternalError:
      description: An unexpected error. Its message is not exposed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            internal:
              value:
                detail: Internal Server Error
  headers:
    RetryAfter:
      description: Seconds to wait.
      schema:
        type: integer
      example: 60

````

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