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

# Get a mandate's remaining budget (ALPHA)

> > **Alpha** — early access.

How much of this standing limit is LEFT right now — what has already been spent under it, what is already earmarked by scheduled payments that have not fired yet, and therefore what remains.

The mandate's `rule` tells you the ceilings; this tells you the consumption. Read it BEFORE you schedule a payment: without it, an over-budget payment is only discovered when the mandate gate denies it at its due date, which is days later, with the payee unpaid and no earlier signal to anyone.

**Both cap flavours are reported, and both must be honoured.** `per_target` lines are metered against the per-payee caps (`max_amount_per_target_in_window`, `max_count_per_target_in_window`); `aggregate` lines roll every payee up into one line per window bucket and are metered against the agent-wide caps (`max_amount_in_window`, `max_count_in_window`). A mandate whose only ceiling is the aggregate one has no per-payee headroom to report, and a caller reading only the `per_target` lines would schedule straight through the agent's overall limit.

**Open earmarks are included on purpose.** A payment that is scheduled but unfired has not spent anything yet, but it WILL at its due date, so budget it does not leave you is budget you do not have. Earmarks are bucketed by the window their due date falls in — a payment due next month consumes NEXT month's bucket — and a past-due one is clamped into the current bucket, since that is the budget it will actually consume when the cron reaches it.

**A `remaining_amount` of `"?"` means the figure could not be summed, and MUST be treated as no headroom.** It appears when a stored amount or cap in that bucket does not parse as a decimal. The mandate gate fails CLOSED on exactly that data, so a payment sent against a `"?"` bucket will be denied; reporting a number instead would promise budget that does not exist. `remaining_count` is unaffected — counts never degrade.

This is ADVISORY, not a reservation. Nothing here holds budget for you, and a concurrent payment can consume the headroom between this read and your write. The gate remains the authority. Use it to refuse what would obviously be denied, not to conclude that a payment is now guaranteed.




## OpenAPI

````yaml /openapi.yaml get /mandates/{mandate_id}/budget
openapi: 3.0.3
info:
  title: Dakota Platform API
  version: 1.0.0
  description: >-
    Combined API specification for Dakota Platform services:

    - Issuance API: Asset minting and burning operations

    - Onboarding API: Know Your Business/Customer verification

    - On/Off Ramp API: Managing on-ramp and off-ramp accounts

    - Recipients API: Managing destinations for KYB'd entities

    - Transactions API: Viewing transaction history across platform operations


    ## Authentication and API Headers


    All API endpoints require the following headers:


    - `x-idempotency-key`: Required for all POST endpoints to ensure request
    idempotency

    - `x-api-key`: Required for authentication across all endpoints


    Note: On /applications endpoints you need a token for authentication instead
    of a x-api-key

    - `x-application-token`: Required for authentication on public /applications
    endpoints (alternative to `x-api-key` where documented)



    ## Rate Limits


    Requests are rate limited per API key. Every response includes the following
    headers:


    | Header | Description |

    | --- | --- |

    | `X-RateLimit-Limit` | Maximum requests allowed in the current one-minute
    window. |

    | `X-RateLimit-Remaining` | Requests remaining in the current window. |

    | `X-RateLimit-Reset` | Absolute Unix timestamp (seconds since epoch) when
    the current rate-limit window resets. |


    When a request is throttled (`429`), responses also include `Retry-After`
    with seconds to wait before retrying.
servers:
  - url: https://api.platform.dakota.xyz
    description: Production environment
  - url: https://api.platform.sandbox.dakota.xyz
    description: Sandbox — safe for testing with simulated data
security:
  - ApiKeyAuth: []
tags:
  - name: Agentic Payments
    x-alpha: true
    description: >-
      Alpha — agent-driven payments: provision agents, draft and approve
      spending mandates, accept reviewed instructions, and manage scheduled
      payments.


      **Prerequisites:** Customer onboarded; signer groups attached for
      recognition.

      **Related:** Wallets, Signer Groups, Transactions
  - name: Mandates
    x-alpha: true
    description: >-
      Alpha — spending mandates: signed, signer-bound authorizations governing
      what may be spent, approved or cancelled by a second recognized signer (§8
      — the dual-control rule that every mandate mutation must be signed by a
      recognized signer OTHER than the bound one). Independent of agents and
      scheduled payments.


      **Prerequisites:** Signer groups attached for recognition.

      **Related:** Signer Groups, Transactions
  - name: Insights
    x-alpha: true
    description: >-
      Alpha — read-only account insight: a deterministic report over a
      customer's agentic activity (funding balances, upcoming obligations,
      failures, mandate headroom and expiry) plus an advisory chat that narrates
      it. Never moves money, never creates or changes anything.


      **Prerequisites:** Customer onboarded; insight is computed from the
      customer's scheduled payments, mandates, and wallets.

      **Related:** Agentic Payments, Mandates
  - name: Customers
    description: >-
      Manage customer entities representing businesses and organizations
      onboarded to Dakota.


      **Prerequisites:** Complete KYB via Onboarding endpoints before initiating
      money movement.

      **Related:** Onboarding, Recipients, Transactions, Accounts, Wallets
  - name: Wallets
    description: >-
      Manage wallets, balances, and wallet-to-signer-group relationships for
      custody and movement controls.


      **Prerequisites:** Customer must exist. Configure signer groups before
      policy-enforced workflows.

      **Related:** Signer Groups, Policies, Transactions, Customers
  - name: Transactions
    description: >-
      Create, cancel, and retrieve transaction records across account and wallet
      flows.


      **Prerequisites:** Accounts or destinations must be configured based on
      flow type.

      **Related:** Accounts, Recipients, Policies, Events
  - name: Recipients
    description: >-
      Manage recipient entities and destination rails used by customers for
      payouts and transfers.


      **Prerequisites:** Customer must be onboarded and active.

      **Related:** Customers, Transactions, Accounts, Onboarding
  - name: Accounts
    description: >-
      Manage account resources used for onramp, offramp, and swap operations.


      **Prerequisites:** Customer must be created and network/asset constraints
      must be known.

      **Related:** Customers, Transactions, Auto Transactions, Info
  - name: Auto Transactions
    description: >-
      Manage automated transaction configurations and execution history for
      account automation workflows.


      **Prerequisites:** Source account must exist and be configured for
      automation.

      **Related:** Accounts, Transactions, Events
  - name: Onboarding
    description: >-
      Manage KYB/KYC onboarding lifecycle, application documents, attestations,
      and verification steps.


      **Prerequisites:** Customer context and required entity/application
      metadata.

      **Related:** Customers, Exceptions, Recipients, Transactions
  - name: Policies
    description: >-
      Define and manage policy objects and rules used for transaction governance
      and risk controls.


      **Prerequisites:** Wallet and signer group resources should be configured
      for enforcement scenarios.

      **Related:** Wallets, Signer Groups, Transactions
  - name: Signer Groups
    description: >-
      Manage signer groups and signer assignments for multi-party authorization
      models.


      **Prerequisites:** Wallets should exist before linking signer groups.

      **Related:** Wallets, Policies, Transactions
  - name: Authentication
    description: >-
      Manage API authentication credentials and key lifecycle for platform
      access.


      **Prerequisites:** Client organization must be provisioned.

      **Related:** Users, Info
  - name: Users
    description: >-
      Manage client users, roles, and identity metadata for platform access
      control.


      **Prerequisites:** Auth credentials and client context must be
      established.

      **Related:** Authentication
  - name: Webhooks
    description: >-
      Manage outbound webhook targets and delivery configuration for event
      notifications.


      **Prerequisites:** Subscriber endpoint must be reachable and secured.

      **Related:** Events, Authentication
  - name: Payouts
    description: >-
      Manage where Dakota sends your accrued developer-fee payouts.


      **Prerequisites:** Auth credentials and client context must be
      established.

      **Related:** Events
  - name: Events
    description: >-
      Retrieve event records emitted by platform operations for audit and
      troubleshooting.


      **Prerequisites:** Requesting client must have access to referenced
      resources.

      **Related:** Webhooks, Transactions, Onboarding
  - name: Info
    description: >-
      Read platform capability metadata, such as supported rails, networks, and
      assets.


      **Prerequisites:** Valid authentication headers.

      **Related:** Accounts, Transactions
  - name: Sandbox
    description: >-
      Trigger sandbox-only simulation endpoints for safe end-to-end integration
      testing with synthetic data. The sandbox host
      (`https://api.platform.sandbox.dakota.xyz`) also accepts a family of
      `X-Sandbox-*` request headers on most write endpoints (`Customers`,
      `Accounts`, `Transactions`, simulate endpoints) that let integrators drive
      deterministic failure modes — pick a preset via `X-Sandbox-Scenario`, or
      compose a custom one with
      `X-Sandbox-Error-Step`/`X-Sandbox-Error-Status`/`X-Sandbox-Error-Message`.
      `X-Sandbox-Instant-Completion` collapses async flows to a single
      synchronous step, and `X-Sandbox-Skip-Auto-Approval` keeps newly created
      KYB applications in `pending` for manual-review testing. All `X-Sandbox-*`
      headers are ignored in production.


      **Prerequisites:** Sandbox environment and test customer data.

      **Related:** Customers, Accounts, Transactions, Onboarding
paths:
  /mandates/{mandate_id}/budget:
    get:
      tags:
        - Mandates
      summary: Get a mandate's remaining budget (ALPHA)
      description: >
        > **Alpha** — early access.


        How much of this standing limit is LEFT right now — what has already
        been spent under it, what is already earmarked by scheduled payments
        that have not fired yet, and therefore what remains.


        The mandate's `rule` tells you the ceilings; this tells you the
        consumption. Read it BEFORE you schedule a payment: without it, an
        over-budget payment is only discovered when the mandate gate denies it
        at its due date, which is days later, with the payee unpaid and no
        earlier signal to anyone.


        **Both cap flavours are reported, and both must be honoured.**
        `per_target` lines are metered against the per-payee caps
        (`max_amount_per_target_in_window`, `max_count_per_target_in_window`);
        `aggregate` lines roll every payee up into one line per window bucket
        and are metered against the agent-wide caps (`max_amount_in_window`,
        `max_count_in_window`). A mandate whose only ceiling is the aggregate
        one has no per-payee headroom to report, and a caller reading only the
        `per_target` lines would schedule straight through the agent's overall
        limit.


        **Open earmarks are included on purpose.** A payment that is scheduled
        but unfired has not spent anything yet, but it WILL at its due date, so
        budget it does not leave you is budget you do not have. Earmarks are
        bucketed by the window their due date falls in — a payment due next
        month consumes NEXT month's bucket — and a past-due one is clamped into
        the current bucket, since that is the budget it will actually consume
        when the cron reaches it.


        **A `remaining_amount` of `"?"` means the figure could not be summed,
        and MUST be treated as no headroom.** It appears when a stored amount or
        cap in that bucket does not parse as a decimal. The mandate gate fails
        CLOSED on exactly that data, so a payment sent against a `"?"` bucket
        will be denied; reporting a number instead would promise budget that
        does not exist. `remaining_count` is unaffected — counts never degrade.


        This is ADVISORY, not a reservation. Nothing here holds budget for you,
        and a concurrent payment can consume the headroom between this read and
        your write. The gate remains the authority. Use it to refuse what would
        obviously be denied, not to conclude that a payment is now guaranteed.
      operationId: getMandateBudget
      parameters:
        - name: mandate_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: The mandate's budget as of `as_of`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MandateBudget'
              example:
                mandate_id: 2vWxMandate00000000000000000
                version: 2
                as_of: 1752000000
                window: MONTHLY
                per_target:
                  - target: 2vWxRecipient000000000000000
                    bucket: 2026-07
                    committed_count: 3
                    committed_amount: '4500'
                    open_count: 1
                    open_amount: '1000'
                aggregate:
                  - target: ''
                    bucket: 2026-07
                    committed_count: 3
                    committed_amount: '4500'
                    open_count: 1
                    open_amount: '1000'
                    remaining_amount: '14500'
        '400':
          description: Invalid request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
              example:
                type: https://docs.dakota.xyz/api-reference/errors#invalid-request
                title: Invalid Request
                status: 400
                detail: invalid mandate id
        '404':
          description: Agentic payments not enabled, or the resource was not found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
              example:
                type: https://docs.dakota.xyz/api-reference/errors#not-found
                title: Not Found
                status: 404
                detail: mandate not found
components:
  schemas:
    MandateBudget:
      type: object
      required:
        - mandate_id
        - version
        - as_of
        - window
        - per_target
        - aggregate
      description: >
        A mandate's remaining spend budget at a point in time. Advisory: nothing
        here reserves budget, and the mandate gate remains the authority at fire
        time.
      properties:
        mandate_id:
          type: string
        version:
          type: integer
          description: >
            The version whose caps these figures are metered against. Amending a
            mandate changes the caps but NOT the spend — usage accrues to the
            mandate, so a raised limit leaves the window's consumption intact
            and a lowered one can leave zero remaining rather than a negative
            balance.
        as_of:
          type: integer
          format: int64
          description: >
            Unix time the windows were derived and the sums taken. Budget is a
            function of time — a MONTHLY bucket empties at the rollover — so the
            figures below are only interpretable against this instant.
        window:
          type: string
          description: >
            The rule's `window` verbatim (`NONE`, `DAILY`, `WEEKLY`, `MONTHLY`)
            — the period each `bucket` spans and the cadence at which budget
            resets. `NONE` is a lifetime cap: one bucket, labelled `lifetime`,
            that never resets.
        per_target:
          type: array
          description: >
            Per-payee lines, metered against `max_amount_per_target_in_window`
            and `max_count_per_target_in_window`. Every configured payee appears
            for the current window even if it has never been paid, so an empty
            budget is reported as zeros rather than as a missing line.
          items:
            $ref: '#/components/schemas/MandateBudgetLine'
        aggregate:
          type: array
          description: >
            One line per window bucket summing EVERY payee, metered against the
            agent-wide `max_amount_in_window` and `max_count_in_window`. This is
            the ceiling on the agent as a whole; honour it alongside
            `per_target`, never instead of it.
          items:
            $ref: '#/components/schemas/MandateBudgetLine'
    ProblemDetails:
      type: object
      required:
        - type
        - title
        - status
      description: |
        Error response following RFC 9457 Problem Details.
        Public API error responses use this format.
      example:
        type: https://docs.dakota.xyz/api-reference/errors#not-found
        title: Customer Not Found
        status: 404
        detail: Customer cst_2abc123 was not found in your organization.
        instance: https://api.platform.dakota.xyz/customers/cst_2abc123
        request_id: req_7f3a8b2c
      properties:
        type:
          type: string
          format: uri
          description: |
            URI reference identifying the problem type.
            Resolves to human-readable documentation.
          example: https://docs.dakota.xyz/api-reference/errors#not-found
        title:
          type: string
          description: >-
            Short, human-readable summary of the problem type. Stable across
            occurrences.
          example: Customer Not Found
        status:
          type: integer
          description: HTTP status code for this occurrence.
          example: 404
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
          example: Customer cst_2abc123 was not found in your organization.
        instance:
          type: string
          format: uri
          description: The request path that triggered this error.
          example: https://api.platform.dakota.xyz/customers/cst_2abc123
        request_id:
          type: string
          description: Unique request identifier. Include when contacting support.
          example: req_7f3a8b2c
        errors:
          type: array
          description: Field-level validation errors (present for validation failures).
          items:
            $ref: '#/components/schemas/ValidationError'
    MandateBudgetLine:
      type: object
      required:
        - target
        - bucket
        - committed_count
        - committed_amount
        - open_count
        - open_amount
      description: >
        One budget line: a window bucket, what has been spent in it, what is
        earmarked against it, and what is left.


        Amounts are decimal strings in the mandate rule's `asset`, matching the
        `rule` fields they are metered against. Counts and amounts are reported
        independently because the rule can cap either, both, or neither.
      properties:
        target:
          type: string
          description: >
            Which payee this line is about — a recipient id under `target_type:
            recipient`, an address under `address`. Empty for `target_type: any`
            (there is one bucket for everything) and always empty on `aggregate`
            lines, which are the roll-up across every payee.
        bucket:
          type: string
          description: >
            The window period this line covers, identified as a date:
            `"2026-07"` for MONTHLY, `"2026-07-13..2026-07-19"` (the full
            inclusive range) for WEEKLY, `"2026-07-13"` for DAILY, and
            `"lifetime"` for window `NONE`, whose single bucket never resets.


            Lines are chronological within a payee (`aggregate`, having no
            payee, is chronological outright), so a payee's CURRENT bucket comes
            first — later buckets exist only where payments are already
            scheduled into future windows, and no bucket earlier than the
            current one is ever reported.
        committed_count:
          type: integer
          description: Payments that have already fired and spent from this bucket.
        committed_amount:
          type: string
          description: Sum of those spends, as a decimal string.
        open_count:
          type: integer
          description: >
            Scheduled payments that have NOT fired yet but will consume this
            bucket at their due date.
        open_amount:
          type: string
          description: Sum of those earmarks, as a decimal string.
        remaining_count:
          type: integer
          description: >
            Payments still permitted in this bucket after committed and open
            ones, floored at 0. ABSENT when the rule sets no count cap for this
            line's scope — absence means "not capped", never "none left".
        remaining_amount:
          type: string
          description: >
            Amount still permitted in this bucket after committed spend and open
            earmarks, floored at 0 and returned as a decimal string. ABSENT when
            the rule sets no amount cap for this line's scope — absence means
            "not capped", never "nothing left".


            **`"?"` means the figure could not be summed and MUST be treated as
            no headroom.** A stored amount or cap in this bucket did not parse
            as a decimal; the mandate gate fails closed on the same data, so a
            payment sent against this bucket will be denied. Do not coerce `"?"`
            to 0 and do not fall back to the rule's cap — both read as headroom
            that is not there.
    ValidationError:
      type: object
      required:
        - field
        - message
      properties:
        field:
          type: string
          description: Field path using dot notation for nested fields.
          example: bank_account.routing_number
        message:
          type: string
          description: Human-readable description of the field error.
          example: Routing number must be exactly 9 digits
        code:
          type: string
          description: Machine-readable error code for this field.
          example: invalid_format
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````