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

# Check AI spend allowance

> Ask whether a customer may spend right now. A read only — it reserves nothing. A customer with no billing policy is answered with `allowed: false, reason: "not_configured"` rather than an error, so an agent always gets a verdict it can act on.



## OpenAPI

````yaml post /v1/ai/billing/check
openapi: 3.1.0
info:
  title: Hyperline Ingest API
  version: 0.0.0
servers:
  - url: https://ingest.hyperline.co
  - url: https://sandbox.ingest.hyperline.co
security: []
paths:
  /v1/ai/billing/check:
    post:
      tags:
        - AI
      summary: Check AI spend allowance
      description: >-
        Ask whether a customer may spend right now. A read only — it reserves
        nothing. A customer with no billing policy is answered with `allowed:
        false, reason: "not_configured"` rather than an error, so an agent
        always gets a verdict it can act on.
      operationId: checkAiBilling
      requestBody:
        description: Check payload.
        content:
          application/json:
            schema:
              type: object
              properties:
                customer:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: >-
                    Customer to bill — the external id your application knows
                    them by, or a Hyperline `cus_…` id. Resolved exactly the way
                    AI telemetry resolves it.
                  example: acme-corp
                agent:
                  type: string
                  minLength: 1
                  maxLength: 128
                  description: >-
                    The agent making the call, as `run({ agent })` names it.
                    Optional, and absent means the customer's shared pool —
                    which is what every call did before per-agent billing
                    existed. Naming an agent only changes anything once an
                    operator has given that agent a billing policy of its own;
                    until then it resolves to the same shared pool and the
                    response says so with `agent: null`.
                  example: invoice-copilot
                action:
                  type: string
                  minLength: 1
                  maxLength: 128
                  description: >-
                    Optional action name. Accepted and reserved for per-action
                    allowances; it does not change the verdict in any mode
                    today.
                  example: deep_research
              required:
                - customer
      responses:
        '200':
          description: Verdict.
          content:
            application/json:
              schema:
                type: object
                properties:
                  agent:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The billing scope that answered: the agent's own slug when
                      it has a policy of its own, and null when the customer's
                      shared pool answered — including when an agent was named
                      but has no policy of its own.
                    example: invoice-copilot
                  allowed:
                    type: boolean
                    description: Whether the customer may spend right now.
                    example: true
                  reason:
                    type:
                      - string
                      - 'null'
                    enum:
                      - not_configured
                      - unsupported_mode
                      - customer_not_found
                      - wallet_missing
                      - credit_pot_missing
                      - blocked
                      - insufficient_balance
                      - insufficient_credits
                      - allowance_exhausted
                      - windows_not_configured
                    description: Why it said no. Null when allowed.
                  balance:
                    type: object
                    properties:
                      denomination:
                        type: string
                        enum:
                          - minor_units
                          - credits
                          - units
                        description: >-
                          What the three numbers count. `minor_units` is the
                          wallet's currency (wallet mode); `credits` is a count
                          of credit units, which has no currency at all (credits
                          mode); `units` is the weighted unit rolling allowances
                          are metered in (windows mode). Read this rather than
                          inferring it from `mode`: a balance is meaningless
                          without its unit.
                        example: minor_units
                      wallet:
                        type: string
                        description: >-
                          The settled source balance — the wallet's balance in
                          wallet mode, the credit pot's balance in credits mode.
                        example: '12500'
                      unsettled:
                        type: string
                        description: >-
                          Consumption recorded but not yet rolled into a wallet
                          transaction. Always `0` in credits mode, where a
                          consume decrements the real credit pot inside its own
                          transaction and leaves nothing in flight.
                        example: '43.218'
                      available:
                        type: string
                        description: >-
                          `wallet - unsettled` — what the customer can still
                          spend, and the only one of the three to gate on in
                          either mode. Correct the instant a consume commits; in
                          wallet mode it may go negative if they overspent
                          between settlements.
                        example: '12456.782'
                    required:
                      - denomination
                      - wallet
                      - unsettled
                      - available
                    description: >-
                      What the customer can spend. In wallet mode this is the
                      shadow balance — micro-consumption never touches the
                      wallet ledger directly. In credits mode it is the credit
                      pot itself, read live. In windows mode the three numbers
                      describe the *binding* window, the one with least room
                      left and therefore the one that will refuse the next call;
                      `meters` carries every window separately.
                  meters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          description: >-
                            The window this meter is for, as the policy names it
                            — `5h`, `7d`, `monthly`.
                          example: 5h
                        included_units:
                          type: string
                          description: The whole allowance for one instance of this window.
                          example: '50000'
                        used_units:
                          type: string
                          description: >-
                            Weighted units consumed inside the open instance,
                            counting the call that just returned. Zero when no
                            instance is open.
                          example: '12500'
                        remaining_units:
                          type: string
                          description: >-
                            `included_units - used_units`, floored at zero. The
                            whole allowance when no instance is open.
                          example: '37500'
                        window_started_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance was anchored — the first
                            consumption after the previous instance expired.
                            Null together with `resets_at` when no instance is
                            open.
                          example: '2026-08-20T09:14:02.113Z'
                        resets_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance expires and the allowance
                            comes back in full. Null when no instance is open:
                            nothing has been consumed since the last one ended,
                            so the clock has not started and the next call is
                            what anchors it.
                          example: '2026-08-20T14:14:02.113Z'
                      required:
                        - key
                        - included_units
                        - used_units
                        - remaining_units
                        - window_started_at
                        - resets_at
                      description: >-
                        One rolling allowance window's live state, including the
                        call that just happened.
                    description: >-
                      Every rolling allowance window, in `windows` mode. Null in
                      every other mode. `allowed` is false as soon as any one of
                      them is at or below the policy floor.
                  overage:
                    type: boolean
                    description: >-
                      True when this `allowed: true` is an overage verdict — the
                      scope is past its boundary and the next call will be
                      priced in USD rather than refused. Never a denial of its
                      own: `allowed` still answers "may I proceed".
                    example: true
                required:
                  - agent
                  - allowed
                  - reason
                  - balance
                  - meters
                  - overage
        '402':
          description: >-
            Not enough credits, or a rolling allowance with no room left.
            Nothing was deducted and no window was incremented.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - not_configured
                      - unsupported_mode
                      - customer_not_found
                      - wallet_missing
                      - credit_pot_missing
                      - pricing_unavailable
                      - insufficient_credits
                      - allowance_exhausted
                      - windows_not_configured
                    description: >-
                      Machine-readable refusal code. Note that
                      `pricing_unavailable` is retained in this enum for
                      compatibility and is no longer returned: usage no rate
                      card can price is recorded at 0 and flagged on the
                      breakdown instead of refusing the call.
                    example: not_configured
                  message:
                    type: string
                    description: Human-readable explanation of the refusal.
                    example: This customer has no AI billing policy
                  balance:
                    type:
                      - object
                      - 'null'
                    properties:
                      denomination:
                        type: string
                        enum:
                          - minor_units
                          - credits
                          - units
                        description: >-
                          What the three numbers count. `minor_units` is the
                          wallet's currency (wallet mode); `credits` is a count
                          of credit units, which has no currency at all (credits
                          mode); `units` is the weighted unit rolling allowances
                          are metered in (windows mode). Read this rather than
                          inferring it from `mode`: a balance is meaningless
                          without its unit.
                        example: minor_units
                      wallet:
                        type: string
                        description: >-
                          The settled source balance — the wallet's balance in
                          wallet mode, the credit pot's balance in credits mode.
                        example: '12500'
                      unsettled:
                        type: string
                        description: >-
                          Consumption recorded but not yet rolled into a wallet
                          transaction. Always `0` in credits mode, where a
                          consume decrements the real credit pot inside its own
                          transaction and leaves nothing in flight.
                        example: '43.218'
                      available:
                        type: string
                        description: >-
                          `wallet - unsettled` — what the customer can still
                          spend, and the only one of the three to gate on in
                          either mode. Correct the instant a consume commits; in
                          wallet mode it may go negative if they overspent
                          between settlements.
                        example: '12456.782'
                    required:
                      - denomination
                      - wallet
                      - unsettled
                      - available
                    description: >-
                      The balance at the moment of the refusal, when the refusal
                      is about money — `insufficient_credits` and
                      `allowance_exhausted` carry it so an agent knows how short
                      it was without a second round trip. Null otherwise.
                  meters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          description: >-
                            The window this meter is for, as the policy names it
                            — `5h`, `7d`, `monthly`.
                          example: 5h
                        included_units:
                          type: string
                          description: The whole allowance for one instance of this window.
                          example: '50000'
                        used_units:
                          type: string
                          description: >-
                            Weighted units consumed inside the open instance,
                            counting the call that just returned. Zero when no
                            instance is open.
                          example: '12500'
                        remaining_units:
                          type: string
                          description: >-
                            `included_units - used_units`, floored at zero. The
                            whole allowance when no instance is open.
                          example: '37500'
                        window_started_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance was anchored — the first
                            consumption after the previous instance expired.
                            Null together with `resets_at` when no instance is
                            open.
                          example: '2026-08-20T09:14:02.113Z'
                        resets_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance expires and the allowance
                            comes back in full. Null when no instance is open:
                            nothing has been consumed since the last one ended,
                            so the clock has not started and the next call is
                            what anchors it.
                          example: '2026-08-20T14:14:02.113Z'
                      required:
                        - key
                        - included_units
                        - used_units
                        - remaining_units
                        - window_started_at
                        - resets_at
                      description: >-
                        One rolling allowance window's live state, including the
                        call that just happened.
                    description: >-
                      Every window's state at the moment of an
                      `allowance_exhausted` refusal, so the caller can see which
                      one ran out and by how much. Null on every other refusal.
                  resets_at:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The soonest instant one of the windows that blocked the
                      call rolls over — the earliest of them, since that is the
                      next moment the answer could change. Null when no blocking
                      window has an open instance, which means the call is
                      larger than a whole allowance and waiting will not help.
                      Null on every other refusal.
                    example: '2026-08-20T14:14:02.113Z'
                required:
                  - code
                  - message
                  - balance
                  - meters
                  - resets_at
        '404':
          description: Customer not found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - not_configured
                      - unsupported_mode
                      - customer_not_found
                      - wallet_missing
                      - credit_pot_missing
                      - pricing_unavailable
                      - insufficient_credits
                      - allowance_exhausted
                      - windows_not_configured
                    description: >-
                      Machine-readable refusal code. Note that
                      `pricing_unavailable` is retained in this enum for
                      compatibility and is no longer returned: usage no rate
                      card can price is recorded at 0 and flagged on the
                      breakdown instead of refusing the call.
                    example: not_configured
                  message:
                    type: string
                    description: Human-readable explanation of the refusal.
                    example: This customer has no AI billing policy
                  balance:
                    type:
                      - object
                      - 'null'
                    properties:
                      denomination:
                        type: string
                        enum:
                          - minor_units
                          - credits
                          - units
                        description: >-
                          What the three numbers count. `minor_units` is the
                          wallet's currency (wallet mode); `credits` is a count
                          of credit units, which has no currency at all (credits
                          mode); `units` is the weighted unit rolling allowances
                          are metered in (windows mode). Read this rather than
                          inferring it from `mode`: a balance is meaningless
                          without its unit.
                        example: minor_units
                      wallet:
                        type: string
                        description: >-
                          The settled source balance — the wallet's balance in
                          wallet mode, the credit pot's balance in credits mode.
                        example: '12500'
                      unsettled:
                        type: string
                        description: >-
                          Consumption recorded but not yet rolled into a wallet
                          transaction. Always `0` in credits mode, where a
                          consume decrements the real credit pot inside its own
                          transaction and leaves nothing in flight.
                        example: '43.218'
                      available:
                        type: string
                        description: >-
                          `wallet - unsettled` — what the customer can still
                          spend, and the only one of the three to gate on in
                          either mode. Correct the instant a consume commits; in
                          wallet mode it may go negative if they overspent
                          between settlements.
                        example: '12456.782'
                    required:
                      - denomination
                      - wallet
                      - unsettled
                      - available
                    description: >-
                      The balance at the moment of the refusal, when the refusal
                      is about money — `insufficient_credits` and
                      `allowance_exhausted` carry it so an agent knows how short
                      it was without a second round trip. Null otherwise.
                  meters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          description: >-
                            The window this meter is for, as the policy names it
                            — `5h`, `7d`, `monthly`.
                          example: 5h
                        included_units:
                          type: string
                          description: The whole allowance for one instance of this window.
                          example: '50000'
                        used_units:
                          type: string
                          description: >-
                            Weighted units consumed inside the open instance,
                            counting the call that just returned. Zero when no
                            instance is open.
                          example: '12500'
                        remaining_units:
                          type: string
                          description: >-
                            `included_units - used_units`, floored at zero. The
                            whole allowance when no instance is open.
                          example: '37500'
                        window_started_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance was anchored — the first
                            consumption after the previous instance expired.
                            Null together with `resets_at` when no instance is
                            open.
                          example: '2026-08-20T09:14:02.113Z'
                        resets_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance expires and the allowance
                            comes back in full. Null when no instance is open:
                            nothing has been consumed since the last one ended,
                            so the clock has not started and the next call is
                            what anchors it.
                          example: '2026-08-20T14:14:02.113Z'
                      required:
                        - key
                        - included_units
                        - used_units
                        - remaining_units
                        - window_started_at
                        - resets_at
                      description: >-
                        One rolling allowance window's live state, including the
                        call that just happened.
                    description: >-
                      Every window's state at the moment of an
                      `allowance_exhausted` refusal, so the caller can see which
                      one ran out and by how much. Null on every other refusal.
                  resets_at:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The soonest instant one of the windows that blocked the
                      call rolls over — the earliest of them, since that is the
                      next moment the answer could change. Null when no blocking
                      window has an open instance, which means the call is
                      larger than a whole allowance and waiting will not help.
                      Null on every other refusal.
                    example: '2026-08-20T14:14:02.113Z'
                required:
                  - code
                  - message
                  - balance
                  - meters
                  - resets_at
        '409':
          description: No billing policy configured.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - not_configured
                      - unsupported_mode
                      - customer_not_found
                      - wallet_missing
                      - credit_pot_missing
                      - pricing_unavailable
                      - insufficient_credits
                      - allowance_exhausted
                      - windows_not_configured
                    description: >-
                      Machine-readable refusal code. Note that
                      `pricing_unavailable` is retained in this enum for
                      compatibility and is no longer returned: usage no rate
                      card can price is recorded at 0 and flagged on the
                      breakdown instead of refusing the call.
                    example: not_configured
                  message:
                    type: string
                    description: Human-readable explanation of the refusal.
                    example: This customer has no AI billing policy
                  balance:
                    type:
                      - object
                      - 'null'
                    properties:
                      denomination:
                        type: string
                        enum:
                          - minor_units
                          - credits
                          - units
                        description: >-
                          What the three numbers count. `minor_units` is the
                          wallet's currency (wallet mode); `credits` is a count
                          of credit units, which has no currency at all (credits
                          mode); `units` is the weighted unit rolling allowances
                          are metered in (windows mode). Read this rather than
                          inferring it from `mode`: a balance is meaningless
                          without its unit.
                        example: minor_units
                      wallet:
                        type: string
                        description: >-
                          The settled source balance — the wallet's balance in
                          wallet mode, the credit pot's balance in credits mode.
                        example: '12500'
                      unsettled:
                        type: string
                        description: >-
                          Consumption recorded but not yet rolled into a wallet
                          transaction. Always `0` in credits mode, where a
                          consume decrements the real credit pot inside its own
                          transaction and leaves nothing in flight.
                        example: '43.218'
                      available:
                        type: string
                        description: >-
                          `wallet - unsettled` — what the customer can still
                          spend, and the only one of the three to gate on in
                          either mode. Correct the instant a consume commits; in
                          wallet mode it may go negative if they overspent
                          between settlements.
                        example: '12456.782'
                    required:
                      - denomination
                      - wallet
                      - unsettled
                      - available
                    description: >-
                      The balance at the moment of the refusal, when the refusal
                      is about money — `insufficient_credits` and
                      `allowance_exhausted` carry it so an agent knows how short
                      it was without a second round trip. Null otherwise.
                  meters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          description: >-
                            The window this meter is for, as the policy names it
                            — `5h`, `7d`, `monthly`.
                          example: 5h
                        included_units:
                          type: string
                          description: The whole allowance for one instance of this window.
                          example: '50000'
                        used_units:
                          type: string
                          description: >-
                            Weighted units consumed inside the open instance,
                            counting the call that just returned. Zero when no
                            instance is open.
                          example: '12500'
                        remaining_units:
                          type: string
                          description: >-
                            `included_units - used_units`, floored at zero. The
                            whole allowance when no instance is open.
                          example: '37500'
                        window_started_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance was anchored — the first
                            consumption after the previous instance expired.
                            Null together with `resets_at` when no instance is
                            open.
                          example: '2026-08-20T09:14:02.113Z'
                        resets_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance expires and the allowance
                            comes back in full. Null when no instance is open:
                            nothing has been consumed since the last one ended,
                            so the clock has not started and the next call is
                            what anchors it.
                          example: '2026-08-20T14:14:02.113Z'
                      required:
                        - key
                        - included_units
                        - used_units
                        - remaining_units
                        - window_started_at
                        - resets_at
                      description: >-
                        One rolling allowance window's live state, including the
                        call that just happened.
                    description: >-
                      Every window's state at the moment of an
                      `allowance_exhausted` refusal, so the caller can see which
                      one ran out and by how much. Null on every other refusal.
                  resets_at:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The soonest instant one of the windows that blocked the
                      call rolls over — the earliest of them, since that is the
                      next moment the answer could change. Null when no blocking
                      window has an open instance, which means the call is
                      larger than a whole allowance and waiting will not help.
                      Null on every other refusal.
                    example: '2026-08-20T14:14:02.113Z'
                required:
                  - code
                  - message
                  - balance
                  - meters
                  - resets_at
        '422':
          description: >-
            The policy cannot bill this: an unsupported mode, a missing wallet
            or credit pot, an unconfigured window card, or usage no rate card
            prices.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    enum:
                      - not_configured
                      - unsupported_mode
                      - customer_not_found
                      - wallet_missing
                      - credit_pot_missing
                      - pricing_unavailable
                      - insufficient_credits
                      - allowance_exhausted
                      - windows_not_configured
                    description: >-
                      Machine-readable refusal code. Note that
                      `pricing_unavailable` is retained in this enum for
                      compatibility and is no longer returned: usage no rate
                      card can price is recorded at 0 and flagged on the
                      breakdown instead of refusing the call.
                    example: not_configured
                  message:
                    type: string
                    description: Human-readable explanation of the refusal.
                    example: This customer has no AI billing policy
                  balance:
                    type:
                      - object
                      - 'null'
                    properties:
                      denomination:
                        type: string
                        enum:
                          - minor_units
                          - credits
                          - units
                        description: >-
                          What the three numbers count. `minor_units` is the
                          wallet's currency (wallet mode); `credits` is a count
                          of credit units, which has no currency at all (credits
                          mode); `units` is the weighted unit rolling allowances
                          are metered in (windows mode). Read this rather than
                          inferring it from `mode`: a balance is meaningless
                          without its unit.
                        example: minor_units
                      wallet:
                        type: string
                        description: >-
                          The settled source balance — the wallet's balance in
                          wallet mode, the credit pot's balance in credits mode.
                        example: '12500'
                      unsettled:
                        type: string
                        description: >-
                          Consumption recorded but not yet rolled into a wallet
                          transaction. Always `0` in credits mode, where a
                          consume decrements the real credit pot inside its own
                          transaction and leaves nothing in flight.
                        example: '43.218'
                      available:
                        type: string
                        description: >-
                          `wallet - unsettled` — what the customer can still
                          spend, and the only one of the three to gate on in
                          either mode. Correct the instant a consume commits; in
                          wallet mode it may go negative if they overspent
                          between settlements.
                        example: '12456.782'
                    required:
                      - denomination
                      - wallet
                      - unsettled
                      - available
                    description: >-
                      The balance at the moment of the refusal, when the refusal
                      is about money — `insufficient_credits` and
                      `allowance_exhausted` carry it so an agent knows how short
                      it was without a second round trip. Null otherwise.
                  meters:
                    type:
                      - array
                      - 'null'
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          description: >-
                            The window this meter is for, as the policy names it
                            — `5h`, `7d`, `monthly`.
                          example: 5h
                        included_units:
                          type: string
                          description: The whole allowance for one instance of this window.
                          example: '50000'
                        used_units:
                          type: string
                          description: >-
                            Weighted units consumed inside the open instance,
                            counting the call that just returned. Zero when no
                            instance is open.
                          example: '12500'
                        remaining_units:
                          type: string
                          description: >-
                            `included_units - used_units`, floored at zero. The
                            whole allowance when no instance is open.
                          example: '37500'
                        window_started_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance was anchored — the first
                            consumption after the previous instance expired.
                            Null together with `resets_at` when no instance is
                            open.
                          example: '2026-08-20T09:14:02.113Z'
                        resets_at:
                          type:
                            - string
                            - 'null'
                          description: >-
                            When the open instance expires and the allowance
                            comes back in full. Null when no instance is open:
                            nothing has been consumed since the last one ended,
                            so the clock has not started and the next call is
                            what anchors it.
                          example: '2026-08-20T14:14:02.113Z'
                      required:
                        - key
                        - included_units
                        - used_units
                        - remaining_units
                        - window_started_at
                        - resets_at
                      description: >-
                        One rolling allowance window's live state, including the
                        call that just happened.
                    description: >-
                      Every window's state at the moment of an
                      `allowance_exhausted` refusal, so the caller can see which
                      one ran out and by how much. Null on every other refusal.
                  resets_at:
                    type:
                      - string
                      - 'null'
                    description: >-
                      The soonest instant one of the windows that blocked the
                      call rolls over — the earliest of them, since that is the
                      next moment the answer could change. Null when no blocking
                      window has an open instance, which means the call is
                      larger than a whole allowance and waiting will not help.
                      Null on every other refusal.
                    example: '2026-08-20T14:14:02.113Z'
                required:
                  - code
                  - message
                  - balance
                  - meters
                  - resets_at
      security:
        - bearer: []
components:
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT

````