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

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Update sub-account direct billing

> Turn direct billing on or off for a sub-account: your client pays us directly for its minutes, from its own card saved with us, at exactly the rate we charge you. Your wallet is never charged or credited for this sub-account, and no Stripe Connect account is needed. Charges show as TFU AI on your client's statement.

**On** makes the sub-account's wallet visible and is refused while rebilling is on (`DIRECT_BILLING_REBILLING_ON`, 409): a sub-account is billed one way at a time. Next, save your client's card on the sub-account's card form in the dashboard. `autoRecharge.enabled` then permits automatic charges to that card: a balance below `thresholdUSD` is charged `rechargeAmountUSD` within 5 minutes, one already below included. Switching auto-recharge on needs that card, so on a sub-account with no card yet, send it after the card is saved. A refusal part-way puts back everything the call changed, Credit Guard included.

Calls use the prepaid minutes first. A call that runs past them is your client's to pay, recorded as debt in minutes that its next top-up clears, never your wallet's. Credit Guard stops its calls at empty instead, so turning direct billing on for a sub-account also turns its Credit Guard on, unless you send `creditGuard`. Switch it off only on purpose: with it off, a card that keeps failing leaves calls running on debt.

**Off** turns auto-recharge off. Minutes your client already paid for stay on the sub-account and keep being used by its calls until they are gone; after that your wallet pays, as for any sub-account you do not rebill. The card stays saved, so switching back on reuses it.

Needs a plan that includes rebilling, like every sub-account billing change, but not Stripe Connect: the card is saved with us, not on your Stripe account. Without the plan the call changes nothing and answers `CAPABILITY_NOT_AVAILABLE` (403).

Allowed customer roles: `agency_admin`. The agency is the one the credential belongs to.

Required API key scope: `billing:write`.



## OpenAPI

````yaml /openapi.yaml put /api/billing/sub-accounts/{locationId}/direct-billing
openapi: 3.1.0
info:
  title: TFUAI Server API
  version: 1.0.0
  description: >-
    API reference for the TFUAI SaaS server.


    All published endpoints are mounted under `/api`. Responses use a standard
    envelope: `{ "success": true, ... }` on success and `{ "success": false,
    "error": "<code>", "message": "..." }` on failure. Branch on the `error`
    code; `message` is for people and its wording can change.


    Product API modules are being launched module by module. This spec currently
    exposes only contracted public modules.


    Authenticate public API requests with an API key in the `Authorization`
    header: `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.teamfollowup.ai
    description: Production API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: >-
      Build the conversation: identity and settings, script, lead context and
      split testing.
  - name: Analytics
    description: >-
      Understand call volume, pickup, booking and transfer metrics within the
      selected reporting scope.
  - name: Billing
    description: >-
      Balances, spend, purchases and sub-account rebilling. Reference and guides
      only; the builder chatbot has no billing playbook.
  - name: Calls
    description: >-
      Review completed calls, recordings, transcripts and campaign run history;
      distinguish observation from placing a new call.
  - name: Campaigns
    description: >-
      Configure what starts calls, who is eligible, calling windows, caller IDs,
      activation and the actions that follow each outcome.


      What runs after a call lands: for each outcome (booked, opted out, asked
      for a callback…), an ordered chain of actions — tag the contact, move a
      pipeline stage, send an SMS, book an appointment. Stored as a graph:
      `nodes` are the actions, `edges` say what follows what, and
      `dispositionEntries` maps each outcome to the node its chain starts at.


      **Pick the narrowest endpoint that does the job.**


      | To | Call | |

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

      | See what fires per outcome | `GET .../workflow?view=summary` | Reads as
      plain text, no graph walking |

      | Add steps to an outcome | `POST .../outcomes/{outcome}/nodes` | Server
      derives node ids, edge ids, handles, layout |

      | Change a message, tag or setting | `PATCH .../workflow` | Merges;
      carries no graph, so it cannot damage one |

      | Remove one step | `DELETE .../nodes/{nodeId}` | Also re-links the chain
      around it |

      | Author or replace the whole graph | `PUT .../workflow` | Replaces
      everything you send |


      `PUT` is the only one that can re-wire, position nodes, build an `if`,
      save an unconfigured draft, or copy a whole workflow — and the only one
      that can overwrite a change someone else made after you read it. Use it
      when you are genuinely authoring the graph, and send `expectedVersion`
      when you do. For everything else the narrower endpoints are both easier
      and safer.
  - name: Contacts
    description: >-
      Find contacts and their calls, manage do-not-call status and identify
      internal contacts excluded from reporting.
  - name: In-call Capabilities
    description: >-
      Configure actions and instructions the agent uses during a live call:
      booking, transfers, lookups and custom skills.
  - name: Master agent
    description: >-
      Run a shared agent and campaign across linked projects; manage
      inheritance, local bindings, synchronization and rollout readiness.
  - name: Native Calendar
    description: >-
      The diary of a sub-account with no CRM: its bookable calendars, the free
      slots they offer, and the appointments on them. Availability is computed
      per request against live bookings and is never cached, because a cached
      slot is one somebody else has already taken.
  - name: Native Contacts
    description: >-
      The people a sub-account with no CRM calls, and the fields it keeps on
      them. This is the system of record for those contacts: there is nowhere
      else they exist. A sub-account with a CRM keeps its contacts there and
      every operation here answers 400 for it.
  - name: Phone Numbers
    description: >-
      Find and manage caller IDs, assign numbers to campaigns and understand
      connected Twilio numbers.
  - name: Projects
    description: >-
      Understand project ownership, inspect configuration and validate the local
      resources used by a campaign.
  - name: TFU Live
    description: >-
      Configure instructions, conversation style, workflows, Chat and call
      handling, then test and go live.
  - name: Voices
    description: >-
      Browse the voice catalogue and select a voice; configure speech and
      listening behavior in Agents.
paths:
  /api/billing/sub-accounts/{locationId}/direct-billing:
    put:
      tags:
        - Billing
      summary: Update sub-account direct billing
      description: >-
        Turn direct billing on or off for a sub-account: your client pays us
        directly for its minutes, from its own card saved with us, at exactly
        the rate we charge you. Your wallet is never charged or credited for
        this sub-account, and no Stripe Connect account is needed. Charges show
        as TFU AI on your client's statement.


        **On** makes the sub-account's wallet visible and is refused while
        rebilling is on (`DIRECT_BILLING_REBILLING_ON`, 409): a sub-account is
        billed one way at a time. Next, save your client's card on the
        sub-account's card form in the dashboard. `autoRecharge.enabled` then
        permits automatic charges to that card: a balance below `thresholdUSD`
        is charged `rechargeAmountUSD` within 5 minutes, one already below
        included. Switching auto-recharge on needs that card, so on a
        sub-account with no card yet, send it after the card is saved. A refusal
        part-way puts back everything the call changed, Credit Guard included.


        Calls use the prepaid minutes first. A call that runs past them is your
        client's to pay, recorded as debt in minutes that its next top-up
        clears, never your wallet's. Credit Guard stops its calls at empty
        instead, so turning direct billing on for a sub-account also turns its
        Credit Guard on, unless you send `creditGuard`. Switch it off only on
        purpose: with it off, a card that keeps failing leaves calls running on
        debt.


        **Off** turns auto-recharge off. Minutes your client already paid for
        stay on the sub-account and keep being used by its calls until they are
        gone; after that your wallet pays, as for any sub-account you do not
        rebill. The card stays saved, so switching back on reuses it.


        Needs a plan that includes rebilling, like every sub-account billing
        change, but not Stripe Connect: the card is saved with us, not on your
        Stripe account. Without the plan the call changes nothing and answers
        `CAPABILITY_NOT_AVAILABLE` (403).


        Allowed customer roles: `agency_admin`. The agency is the one the
        credential belongs to.


        Required API key scope: `billing:write`.
      operationId: put-billing-sub-accounts-by-locationId-direct-billing
      parameters:
        - name: locationId
          in: path
          required: true
          schema:
            type: string
            minLength: 1
          description: The sub-account's Location ID.
          example: loc_9f7a123
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            minLength: 8
            maxLength: 255
          description: >-
            Optional. A retry with the same key returns the first answer with
            `idempotentReplay: true`.
          example: rebill-bright-dental-2026-09-15
      requestBody:
        required: true
        description: On, optionally with auto-recharge and Credit Guard; or off.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillingDirectBillingRequest'
            examples:
              'on':
                value:
                  enabled: true
                  autoRecharge:
                    enabled: false
                    thresholdUSD: 25
                    rechargeAmountUSD: 100
              onWithoutCreditGuard:
                value:
                  enabled: true
                  creditGuard:
                    enabled: false
              'off':
                value:
                  enabled: false
      responses:
        '200':
          description: The sub-account after the change.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingSubAccountWriteResponse'
              examples:
                default:
                  value:
                    success: true
                    data:
                      subAccount:
                        locationId: loc_9f7a123
                        name: Bright Dental
                        isLive: true
                        billingMode: REBILLING
                        rebilling:
                          enabled: true
                          clientRatePerMinute: 0.45
                        directBilling:
                          enabled: false
                          card: null
                        wallet:
                          balanceMinutes: 64.5
                          balanceUSD: 29.03
                          debtMinutes: 0
                          status: LOW_BALANCE
                          visibility: ENABLED
                        autoRecharge:
                          enabled: true
                          thresholdUSD: 25
                          rechargeAmountUSD: 100
                          blockedReason: null
                          requiresAction: false
                          recommendedAction: null
                          lastSuccessfulRechargeAt: '2026-09-10T09:30:00.000Z'
                          lastFailureAt: null
                        creditGuard:
                          enabled: false
                        pendingCredits:
                          count: 0
                          minutes: 0
                          amountUSD: 0
                          items: []
                        creditBatches:
                          - id: BKT-51c0
                            purchasedAt: '2026-09-10T09:30:00.000Z'
                            minutesPurchased: 200
                            minutesRemaining: 64.5
                            valueRemainingUSD: 29.03
                            ratePerMinute: 0.45
                            isBonus: false
                            expiresAt: null
                            isExpired: false
        '400':
          description: >-
            The body or path is invalid (`BadRequest`: `errors` names each field
            to fix, and a field the body should not have is named `body`), the
            Idempotency-Key is missing or malformed (`IDEMPOTENCY_KEY_REQUIRED`,
            `IDEMPOTENCY_KEY_INVALID`), or a self-serve agency sent
            `thresholdMinutes` (`THRESHOLD_FIXED_FOR_SELF_SERVE`). A change the
            owning service refuses arrives here too: `REBILLING_UPDATE_FAILED`,
            `AUTO_RECHARGE_CONFIGURATION_INVALID`, `CREDIT_GUARD_UPDATE_FAILED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: BadRequest
                    message: >-
                      Something here doesn't look right. Please check it and try
                      again.
                    errors:
                      - field: enabled
                        code: FieldRequired
                        message: Please fill this in.
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unauthorized
                    message: Please sign in to continue.
        '403':
          description: >-
            The credential lacks `billing:write` (`InsufficientScope`), is not
            an agency admin's (`Forbidden`), or the plan does not include
            rebilling (`CAPABILITY_NOT_AVAILABLE`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: InsufficientScope
                    message: >-
                      This access key does not allow this action. Please ask
                      your account admin to change its permissions.
                    requiredScope: billing:write
        '404':
          description: A named sub-account, plan or request is not this agency's.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: NotFound
                    message: We couldn't find that. It may have been moved or deleted.
                    unknownLocationIds:
                      - loc_9f7a123
        '409':
          description: >-
            The change conflicts with the current state, and nothing was
            changed. `error` says which: `STRIPE_NOT_CONNECTED`,
            `SUB_ACCOUNT_WALLET_REQUIRED`, `REBILLING_OFF`,
            `PENDING_CREDITS_EXIST`, `PROJECT_RATE_NEEDS_CONFIRMATION`,
            `NO_USABLE_CARD`, `PAYMENT_METHOD_SELECTION_REQUIRED`,
            `USABLE_DEFAULT_PAYMENT_METHOD_REQUIRED`,
            `AUTO_RECHARGE_NOT_ENABLED`, `AUTO_RECHARGE_CARD_REQUIRED`,
            `PRIOR_PROJECT_PAYMENT_CONFLICT`,
            `PROJECT_WALLET_BACKFILL_REQUIRED`, `PAYMENT_METHOD_UNUSABLE`,
            `STALE_PROJECT_BILLING_CONFIGURATION`,
            `AUTO_RECHARGE_RECONCILIATION_REQUIRED`,
            `AUTO_RECHARGE_PAYMENT_IN_PROGRESS`, `DIRECT_BILLING_ACTIVE` (the
            sub-account is on direct billing), `DIRECT_BILLING_REBILLING_ON` (it
            is rebilled), `IDEMPOTENT_REPLAY` (the funding layer recognised this
            charge and did not repeat it; read the wallet back),
            `SUB_ACCOUNT_CHANGED_DURING_WRITE` (someone else changed the
            sub-account mid-write), or an Idempotency-Key problem:
            `IDEMPOTENCY_KEY_REUSED`, `IDEMPOTENCY_IN_PROGRESS`,
            `IDEMPOTENCY_OUTCOME_UNKNOWN` (an earlier attempt on that key may
            have charged, so use a new one).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: DIRECT_BILLING_REBILLING_ON
                    message: >-
                      Client billing is on for this sub-account. Turn it off
                      first, as a sub-account is billed one way at a time.
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: TooManyRequests
                    message: That's a lot at once. Please wait a moment and try again.
        '500':
          description: >-
            Unexpected server error (`InternalError`), a rejected change
            (`REBILLING_UPDATE_FAILED`, `AUTO_RECHARGE_CONFIGURATION_INVALID`,
            `CREDIT_GUARD_UPDATE_FAILED`), a rollback that could not complete
            (`LINK_ROLLBACK_INCOMPLETE`, `REBILLING_ROLLBACK_INCOMPLETE`,
            `DIRECT_BILLING_ROLLBACK_INCOMPLETE`), a bulk change that applied to
            only some sub-accounts (`CREDIT_GUARD_PARTIALLY_APPLIED`), or a
            change that could not be saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: InternalError
                    message: >-
                      Something went wrong on our side. Please try again in a
                      moment.
                    ref: 3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b
        '503':
          description: >-
            Stripe could not be reached, or could not confirm the card. Nothing
            was changed; retry with the same Idempotency-Key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingWriteErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: PAYMENT_METHOD_PROVIDER_UNAVAILABLE
                    message: >-
                      We couldn't check your billing card. Please try again in a
                      moment.
                    ref: 3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request PUT \
              --url https://api.teamfollowup.ai/api/billing/sub-accounts/{locationId}/direct-billing \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "enabled": true,
              "autoRecharge": {
                "enabled": false,
                "thresholdUSD": 25,
                "rechargeAmountUSD": 100
              }
            }'
components:
  schemas:
    BillingDirectBillingRequest:
      type: object
      additionalProperties: false
      description: On, optionally with auto-recharge and Credit Guard; or off.
      required:
        - enabled
      properties:
        enabled:
          type: boolean
          description: '`true` to turn direct billing on, `false` to turn it off.'
        autoRecharge:
          type: object
          additionalProperties: false
          description: >-
            Only with `enabled: true`. Set the sub-account's auto-recharge in
            the same step. On needs your client's card saved first.
          required:
            - enabled
          properties:
            enabled:
              type: boolean
              description: Whether the sub-account tops itself up.
            thresholdUSD:
              type: number
              minimum: 10
              description: >-
                Top up when the dollar balance falls below this. Leave out to
                keep the stored value, or to take the platform default of $50
                when the sub-account has never had one.
            rechargeAmountUSD:
              type: number
              exclusiveMinimum: 0
              description: >-
                Dollars each top-up charges the client's card. Leave out to keep
                the stored value, or to take the platform default of $200 when
                the sub-account has never had one. Name it rather than
                inheriting it: this is the figure a client is charged without
                being asked again.
        creditGuard:
          type: object
          additionalProperties: false
          description: >-
            Only with `enabled: true`. Leave out to turn Credit Guard on for a
            sub-account that was not on direct billing, and to keep it as it is
            for one that was.
          required:
            - enabled
          properties:
            enabled:
              type: boolean
              description: >-
                Whether the sub-account stops its own calls when its wallet is
                empty.
    BillingSubAccountWriteResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          example: true
        idempotentReplay:
          type: boolean
          description: >-
            Present, and true, when this answer is a replay of an earlier
            request with the same Idempotency-Key.
        data:
          type: object
          additionalProperties: false
          required:
            - subAccount
          properties:
            subAccount:
              $ref: '#/components/schemas/BillingSubAccountDetail'
            charge:
              $ref: '#/components/schemas/BillingChargeResult'
    BillingWriteErrorResponse:
      type: object
      description: >-
        How a Billing write answers when it fails: the standard error envelope,
        plus the fields below where they apply.
      required:
        - success
        - error
        - message
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: >-
            A stable code for what went wrong. Branch on this: the same failure
            always answers with the same code.
          example: NotFound
        message:
          type: string
          description: >-
            One plain sentence for a person: what happened and what to do next.
            Show it, never parse it: the wording can change, and browser users
            get it in their own language. API keys and OAuth apps always get
            English.
          example: We couldn't find that. It may have been moved or deleted.
        errors:
          type: array
          description: >-
            Sent when specific fields were refused: one entry for each field to
            fix.
          items:
            type: object
            additionalProperties: false
            required:
              - field
              - code
              - message
            properties:
              field:
                type: string
                description: Where the value sits in the request, as a dotted path.
                example: name
              code:
                type: string
                description: A stable code for what is wrong with the value.
                example: FieldRequired
              message:
                type: string
                description: One plain sentence for a person.
                example: Please fill this in.
        details:
          type: object
          additionalProperties: {}
          description: >-
            Data your code may need to act on the failure, such as ids or
            limits. Never text for people.
        ref:
          type: string
          description: >-
            Sent only when the failure was on our side. Quote it to support so
            they can find the request. It matches the `x-request-id` response
            header.
          example: 3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b
        requiredScope:
          type: string
          description: On `InsufficientScope`, the scope the credential was missing.
        code:
          type: string
          description: >-
            Sent only to a signed-in browser whose security check failed: an
            older, more specific code some apps still read. API keys and OAuth
            apps never get it.
        idempotentReplay:
          type: boolean
          description: >-
            Present, and true, when this answer is a replay of an earlier
            request with the same Idempotency-Key.
        unknownLocationIds:
          type: array
          items:
            type: string
          description: Named sub-accounts that are not this agency's.
        withoutWalletLocationIds:
          type: array
          items:
            type: string
          description: Named sub-accounts with no wallet yet.
        failedLocationId:
          type: string
          description: The sub-account a multi-step change failed on.
        rollbackFailedLocationIds:
          type: array
          items:
            type: string
          description: >-
            Sub-accounts that could not be put back. Review them in the
            dashboard.
        cause:
          type: string
          description: For a failed rollback, the code of the failure that triggered it.
        rebillingLeftOn:
          type: boolean
          description: The charge's outcome is unknown, so rebilling was left on.
        requestNumber:
          type: string
          description: For a failed purchase, the request it made.
        requestedCount:
          type: integer
          minimum: 0
          description: >-
            On `CREDIT_GUARD_PARTIALLY_APPLIED`, how many sub-accounts were
            named.
        appliedCount:
          type: integer
          minimum: 0
          description: >-
            On `CREDIT_GUARD_PARTIALLY_APPLIED`, how many the change reached.
            Read the rest back.
        projectCardCharged:
          type: boolean
          description: >-
            On a refused charge, present and false when the client's card was
            never touched.
        pendingCredits:
          type: integer
          minimum: 0
          description: Client payments waiting for credit.
        recommendedAction:
          type: string
          description: What to do next, for example `UPDATE_PAYMENT_METHOD`.
        declineCode:
          type: string
          description: The card issuer's reason.
        failureCategory:
          type: string
          description: What kind of failure it was.
        errorCode:
          type: string
          description: The payment provider's code.
        requiresAction:
          type: boolean
          description: Whether someone has to act first.
        healthStatus:
          type: string
          description: Why a card cannot be used.
        paymentMethods:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: >-
            On `PAYMENT_METHOD_SELECTION_REQUIRED`, the usable cards to choose
            from in the dashboard.
        paymentReviewRequired:
          type: boolean
          description: A payment is waiting for our support team.
        reconciliationRequired:
          type: boolean
          description: The state needs reconciling before it can change.
        cooldownEndsAt:
          type: string
          format: date-time
          description: >-
            On `FREE_PLAN_BRONZE_COOLDOWN`, when Bronze can be bought again.
            Left out while an earlier Bronze is still being paid for.
        next:
          type: object
          additionalProperties: false
          description: On a Free plan refusal, the step that lifts the limit.
          required:
            - step
            - label
            - page
          properties:
            step:
              type: string
              description: What to do, for example `upgrade`.
            label:
              type: string
              description: A label for the button that does it.
            page:
              type: string
              description: The dashboard page that does it, as a path.
      additionalProperties: false
    BillingSubAccountDetail:
      type: object
      additionalProperties: false
      required:
        - locationId
        - name
        - isLive
        - billingMode
        - rebilling
        - directBilling
        - wallet
        - autoRecharge
        - creditGuard
        - pendingCredits
        - creditBatches
      properties:
        locationId:
          type: string
          description: The sub-account's Location ID.
        name:
          type:
            - string
            - 'null'
          description: Display name. A label only; it can change.
        isLive:
          type:
            - boolean
            - 'null'
          description: >-
            `false` when the sub-account is paused. `null` when its status is
            unknown.
        billingMode:
          type: string
          enum:
            - DIRECT
            - REBILLING
            - AGENCY_WALLET
          description: >-
            Who pays for this sub-account's calls. `DIRECT`: your client pays us
            directly, at your rate, from a card saved with us. `REBILLING`: your
            client pays you, at the rate you set. `AGENCY_WALLET`: your wallet
            pays.
        rebilling:
          type: object
          additionalProperties: false
          required:
            - enabled
            - clientRatePerMinute
          properties:
            enabled:
              type: boolean
              description: >-
                Whether this sub-account pays for its own calls from its own
                wallet.
            clientRatePerMinute:
              type:
                - number
                - 'null'
              description: >-
                What you charge this sub-account per minute. `null` when
                rebilling is off.
        directBilling:
          type: object
          additionalProperties: false
          required:
            - enabled
            - card
          properties:
            enabled:
              type: boolean
              description: >-
                Whether your client pays us directly for this sub-account's
                minutes. Your wallet is never charged or credited for it.
            card:
              description: >-
                The card we charge, read live from Stripe. `null` when direct
                billing is off.
              anyOf:
                - type: object
                  additionalProperties: false
                  required:
                    - status
                    - brand
                    - last4
                    - expMonth
                    - expYear
                  properties:
                    status:
                      type: string
                      enum:
                        - OK
                        - NO_CARD
                        - NO_CUSTOMER
                        - NO_DEFAULT_RECORDED
                        - NOT_MIGRATED
                        - WRONG_ACCOUNT
                        - PROVIDER_UNAVAILABLE
                      description: >-
                        `OK` when a usable card is chosen. `NO_CUSTOMER` or
                        `NO_CARD` until a card is saved. `PROVIDER_UNAVAILABLE`
                        when Stripe could not be read just now.
                    brand:
                      type:
                        - string
                        - 'null'
                      description: Card brand, for example `visa`.
                    last4:
                      type:
                        - string
                        - 'null'
                      description: Last four digits.
                    expMonth:
                      type:
                        - integer
                        - 'null'
                      description: Expiry month.
                    expYear:
                      type:
                        - integer
                        - 'null'
                      description: Expiry year.
                - type: 'null'
        wallet:
          type: object
          additionalProperties: false
          required:
            - balanceMinutes
            - balanceUSD
            - debtMinutes
            - status
            - visibility
          properties:
            balanceMinutes:
              type: number
              description: Minutes left, bonus minutes included, expired batches excluded.
            balanceUSD:
              type: number
              description: Value of the paid minutes left.
            debtMinutes:
              type: number
              description: Minutes owed.
            status:
              type: string
              enum:
                - ACTIVE
                - LOW_BALANCE
                - IN_DEBT
                - DEPLETED
              description: >-
                `ACTIVE` above the low mark, `LOW_BALANCE` at or under it,
                `IN_DEBT` empty and owing, `DEPLETED` empty.
            visibility:
              type: string
              enum:
                - ENABLED
                - DISABLED
              description: Whether the sub-account can see its wallet.
        autoRecharge:
          type: object
          additionalProperties: false
          required:
            - enabled
            - thresholdUSD
            - rechargeAmountUSD
            - blockedReason
            - requiresAction
            - recommendedAction
            - lastSuccessfulRechargeAt
            - lastFailureAt
          properties:
            enabled:
              type: boolean
              description: Whether the sub-account tops itself up.
            thresholdUSD:
              type:
                - number
                - 'null'
              description: >-
                Top up when the wallet's dollar balance falls below this. `null`
                when not set.
            rechargeAmountUSD:
              type:
                - number
                - 'null'
              description: How much each top-up charges, in dollars. `null` when not set.
            blockedReason:
              type:
                - string
                - 'null'
              description: >-
                Why an enabled auto-recharge cannot charge, for example
                `NO_CUSTOMER`.
            requiresAction:
              type: boolean
              description: Whether someone has to act before it can charge again.
            recommendedAction:
              type:
                - string
                - 'null'
              description: What to do, for example `UPDATE_PAYMENT_METHOD`.
            lastSuccessfulRechargeAt:
              type:
                - string
                - 'null'
              format: date-time
              description: The last top-up that charged.
            lastFailureAt:
              type:
                - string
                - 'null'
              format: date-time
              description: The last top-up that failed.
        creditGuard:
          type: object
          additionalProperties: false
          required:
            - enabled
          properties:
            enabled:
              type: boolean
              description: >-
                Whether this sub-account stops its own calls when its wallet is
                empty.
        pendingCredits:
          type: object
          additionalProperties: false
          required:
            - count
            - minutes
            - amountUSD
            - items
          properties:
            count:
              type: integer
              minimum: 0
              description: Payments waiting for credit.
            minutes:
              type: number
              description: Minutes they will add.
            amountUSD:
              type: number
              description: What was paid.
            items:
              type: array
              items:
                $ref: '#/components/schemas/BillingPendingCreditItem'
        creditBatches:
          type: array
          description: Oldest first, the order minutes are drawn down.
          items:
            $ref: '#/components/schemas/BillingCreditBatch'
    BillingChargeResult:
      type: object
      additionalProperties: false
      required:
        - status
        - amountUSD
        - minutesAdded
      properties:
        status:
          type: string
          enum:
            - SUCCEEDED
            - CREDIT_PENDING
          description: >-
            `SUCCEEDED`: the card was charged and the wallet credited.
            `CREDIT_PENDING`: the card was charged and the minutes have not
            landed yet, so `minutesAdded` is null; read the wallet back. A retry
            with the same `Idempotency-Key` replays this same answer with
            `idempotentReplay: true` and charges nothing.
        amountUSD:
          type: number
          description: Dollars charged.
        minutesAdded:
          type:
            - number
            - 'null'
          description: >-
            Minutes added to the sub-account wallet, or `null` when not
            reported.
    BillingPendingCreditItem:
      type: object
      additionalProperties: false
      required:
        - id
        - minutes
        - amountUSD
        - ratePerMinute
        - reason
        - createdAt
        - expiresAt
      properties:
        id:
          type:
            - string
            - 'null'
          description: Reference.
        minutes:
          type: number
          description: Minutes it will add.
        amountUSD:
          type: number
          description: What was paid.
        ratePerMinute:
          type:
            - number
            - 'null'
          description: The rate paid.
        reason:
          type:
            - string
            - 'null'
          description: Why it is waiting.
        createdAt:
          type:
            - string
            - 'null'
          format: date-time
          description: When the payment arrived.
        expiresAt:
          type:
            - string
            - 'null'
          format: date-time
          description: When it stops waiting.
    BillingCreditBatch:
      type: object
      additionalProperties: false
      required:
        - id
        - purchasedAt
        - minutesPurchased
        - minutesRemaining
        - valueRemainingUSD
        - ratePerMinute
        - isBonus
        - expiresAt
        - isExpired
      properties:
        id:
          type: string
          description: Batch reference.
        purchasedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: When it was bought.
        minutesPurchased:
          type: number
          description: Minutes bought.
        minutesRemaining:
          type: number
          description: Minutes left. `0` once expired.
        valueRemainingUSD:
          type: number
          description: Value of the minutes left. `0` for bonus batches.
        ratePerMinute:
          type:
            - number
            - 'null'
          description: The rate it was bought at.
        isBonus:
          type: boolean
          description: Gifted rather than paid for.
        expiresAt:
          type:
            - string
            - 'null'
          format: date-time
          description: When it expires. `null` for never.
        isExpired:
          type: boolean
          description: Whether it has expired.
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````

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