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

> ## Agent Instructions
> Money is always a decimal string at the currency's precision (for example "29.00"), paired with an ISO 4217 currency field. Never use minor units.
> Build against the sandbox first: base URL https://sandbox-api.bachs.io with sk_sandbox_ keys. Production is https://api.bachs.io with sk_live_ keys; going live is a key swap.
> Treat webhooks (for example collection.succeeded) as the source of truth for fulfilment, never client-side events or redirects.
> Subscriptions are created by completing a checkout for a recurring product. There is no direct create-subscription endpoint.
> IDs carry resource prefixes (cust_, prod_, sub_, chk_, inv_, ref_) and timestamps are ISO 8601 UTC.

# Update payout schedule

> Set the payout schedule for your account, or for a connected account named by `X-Account-Id`. A currency you leave out of `schedule_by_currency` keeps the schedule it has; a currency you name is replaced in full. See [Payout Schedules](/guides/payouts/payout-schedules).



## OpenAPI

````yaml /docs/openapi/openapi.json post /v1/balance_settings
openapi: 3.0.3
info:
  title: Bachs API
  version: 1.0.0
  description: >-
    The Bachs API lets you accept payments, manage subscriptions, and move money
    across African markets.


    - **Authentication:** pass your secret key as `Authorization: Bearer
    sk_...`. See [Authentication](/authentication) for keys, scopes, and sandbox
    vs production.

    - **Errors:** every error returns a flat `{ "detail", "error_code",
    "doc_url" }`. See [Errors](/errors).

    - **Pagination:** list endpoints return `{ items, pagination }`. See
    [Pagination](/guides/pagination).

    - **Idempotency:** retry `POST` safely with the `Idempotency-Key` header.
    See [Idempotency](/guides/idempotency).

    - **Base URLs and rate limits:** see the
    [Introduction](/api-reference/overview).
  contact:
    name: Bachs Support
    url: https://bachs.io
servers:
  - url: https://api.bachs.io
    description: Production
  - url: https://sandbox-api.bachs.io
    description: Sandbox
security:
  - ApiKeyAuth: []
tags:
  - name: Payments
    description: Accept payments from customers
  - name: Refunds
    description: Create and manage customer refunds
  - name: Disputes
    description: Respond to chargebacks and manage dispute evidence
  - name: Balances
    description: View balances and account information
  - name: Conversions
    description: Quote, execute, and query currency conversions
  - name: Payouts
    description: Withdraw funds to external accounts
  - name: Webhooks
    description: Receive real-time payment notifications
  - name: Authentication
    description: API key management and authentication
  - name: Customers
    description: Create and manage customers
  - name: Products
    description: Define and manage your billing catalog
  - name: Product Groups
    description: Bundle products for multi-plan checkout
  - name: Media
    description: Upload files and get an upload_id to attach to products
  - name: Checkouts
    description: Create and manage API-driven checkouts without products
  - name: Subscriptions
    description: >-
      Recurring billing. Subscriptions are created through checkout; manage them
      here.
  - name: Customer sessions
    description: >-
      Open a hosted portal session so a customer can manage their own
      subscriptions, invoices and cards.
  - name: Accounts
    description: >-
      Create the accounts your platform onboards, request their capabilities,
      walk them through their requirements, and read what they still owe.
  - name: Transfers
    description: Move funds between your platform and the accounts you own.
  - name: Platform Fees
    description: Read the platform's cut of an account's sale.
paths:
  /v1/balance_settings:
    post:
      tags:
        - Balances
      summary: Update payout schedule
      description: >-
        Set the payout schedule for your account, or for a connected account
        named by `X-Account-Id`. A currency you leave out of
        `schedule_by_currency` keeps the schedule it has; a currency you name is
        replaced in full. See [Payout
        Schedules](/guides/payouts/payout-schedules).
      operationId: updatePayoutSchedule
      parameters:
        - name: X-Account-Id
          in: header
          required: false
          schema:
            type: string
          description: >-
            Set the schedule of a connected account you own instead of your own.
            Same resolution every other API-key route uses: the account must be
            yours or one you own, or the request 404s.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PayoutSettingsRequest'
            example:
              schedule_by_currency:
                NGN:
                  interval: weekly
                  weekly_payout_days:
                    - monday
                    - thursday
                  anchor_hour_utc: 9
                  minimum_amount: '5000.00'
      responses:
        '200':
          description: The account's payout schedule after the write.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutSettingsResponse'
              example:
                schedule_by_currency:
                  NGN:
                    currency: NGN
                    payout_currency: NGN
                    interval: weekly
                    weekly_payout_days:
                      - monday
                      - thursday
                    monthly_payout_days: null
                    anchor_hour_utc: 9
                    minimum_amount: '5000.00'
                    next_run_at: '2026-08-13T09:00:00.000Z'
                    last_run_at: null
                    last_withdrawal_id: null
                    disabled_reason: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - ApiKeyAuth:
            - balance:write
components:
  schemas:
    PayoutSettingsRequest:
      type: object
      description: The payout schedule to set, one call at a time.
      properties:
        schedule_by_currency:
          type: object
          nullable: true
          additionalProperties:
            $ref: '#/components/schemas/PayoutScheduleRequest'
          description: >-
            Payout schedules to set, keyed by the balance currency each one
            governs. A currency you leave out keeps the schedule it has, so one
            call changes NGN without touching USD.
    PayoutSettingsResponse:
      type: object
      properties:
        schedule_by_currency:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/PayoutScheduleResponse'
          description: >-
            Payout schedules, keyed by the balance currency each one governs. A
            currency with no schedule is absent rather than present and empty,
            so you can tell "never configured" from "pays out weekly".
    PayoutScheduleRequest:
      type: object
      description: >-
        Set when a currency pays out. Replaces the currency's schedule rather
        than patching it: a field you omit is cleared, not kept.
      required:
        - interval
      properties:
        interval:
          type: string
          enum:
            - manual
            - instant
            - daily
            - weekly
            - monthly
          description: >-
            How often this currency pays out.


            - `manual`: nothing is paid out automatically. The balance stays put
            until you call Create Payout.

            - `instant`: about a minute after funds settle, so several times on
            a busy day and not at all on a quiet one. Collections settling close
            together are paid out together, in one payout carrying one fee.

            - `daily`: once a day, at `anchor_hour_utc`.

            - `weekly`: once a week, on `weekly_anchor`, at `anchor_hour_utc`.

            - `monthly`: once a month, on `monthly_anchor`, at
            `anchor_hour_utc`.
          example: daily
        weekly_payout_days:
          type: array
          nullable: true
          items:
            type: string
            enum:
              - monday
              - tuesday
              - wednesday
              - thursday
              - friday
              - saturday
              - sunday
          description: >-
            Weekdays a weekly payout lands on. Listing more than one means more
            than one payout a week: `["monday", "thursday"]` pays twice.
            Defaults to `["monday"]`. Sending it on any other interval is
            rejected rather than ignored, so a schedule never quietly loses the
            days you asked for.
          example:
            - monday
            - thursday
        monthly_payout_days:
          type: array
          nullable: true
          items:
            type: integer
            minimum: 1
            maximum: 31
          description: >-
            Days of the month a monthly payout lands on, each `1` to `31`.
            Listing more than one means more than one payout a month. 29, 30 and
            31 land on the last day of a shorter month, so `[31]` pays on the
            31st of January and the 28th of February. Defaults to `[1]`. Sending
            it on any other interval is rejected.
          example:
            - 1
            - 15
        anchor_hour_utc:
          type: integer
          nullable: true
          minimum: 0
          maximum: 23
          description: >-
            The UTC hour to run at, `0` to `23`. Defaults to `10`. Ignored by
            `manual` and `instant`.
          example: 9
        payout_currency:
          type: string
          nullable: true
          description: >-
            The currency to deliver the money in, in ISO 4217 format. Defaults
            to the balance currency. Setting it to something else converts each
            run at the rate of the day it runs, and is available out of USD and
            stablecoin balances only. Converting out of a local settlement
            currency is rejected here rather than at run time.
          example: NGN
        minimum_amount:
          type: string
          nullable: true
          description: >-
            A floor for a run, as a decimal string (e.g. "5000.00") in the
            balance currency. A run whose eligible total is below it pays
            nothing and the money rolls into the next run. Omit for no floor.
          example: '5000.00'
    PayoutScheduleResponse:
      type: object
      description: The payout schedule for one currency of one account.
      properties:
        currency:
          type: string
          description: >-
            The balance currency this schedule governs, in ISO 4217 format. Each
            currency is scheduled independently.
          example: NGN
        payout_currency:
          type: string
          description: >-
            The currency the money is delivered in. Equal to `currency` unless
            the schedule converts, in which case each run is quoted at the rate
            of the day it runs.
          example: NGN
        interval:
          type: string
          enum:
            - manual
            - instant
            - daily
            - weekly
            - monthly
          description: >-
            How often this currency pays out.


            - `manual`: nothing is paid out automatically. The balance stays put
            until you call Create Payout.

            - `instant`: about a minute after funds settle, so several times on
            a busy day and not at all on a quiet one. Collections settling close
            together are paid out together, in one payout carrying one fee.

            - `daily`: once a day, at `anchor_hour_utc`.

            - `weekly`: once a week, on `weekly_anchor`, at `anchor_hour_utc`.

            - `monthly`: once a month, on `monthly_anchor`, at
            `anchor_hour_utc`.
          example: daily
        weekly_payout_days:
          type: array
          nullable: true
          items:
            type: string
            enum:
              - monday
              - tuesday
              - wednesday
              - thursday
              - friday
              - saturday
              - sunday
          description: >-
            Weekdays a weekly payout lands on. Listing more than one means more
            than one payout a week: `["monday", "thursday"]` pays twice. Null on
            every other interval, because nothing else reads it.
          example:
            - monday
            - thursday
        monthly_payout_days:
          type: array
          nullable: true
          items:
            type: integer
            minimum: 1
            maximum: 31
          description: >-
            Days of the month a monthly payout lands on, each `1` to `31`.
            Listing more than one means more than one payout a month. 29, 30 and
            31 land on the last day of a shorter month, so `[31]` pays on the
            31st of January and the 28th of February. Null on every other
            interval.
          example:
            - 1
            - 15
        anchor_hour_utc:
          type: integer
          nullable: true
          minimum: 0
          maximum: 23
          description: >-
            The UTC hour a scheduled run happens, `0` to `23`. Defaults to `10`.
            Null on `manual` and `instant`, which have no schedule.
          example: 9
        minimum_amount:
          type: string
          nullable: true
          description: >-
            The floor a run has to reach before it pays anything, as a decimal
            string in `currency`. A run below it pays nothing and the money
            rolls into the next run. Null means no floor.
          example: '5000.00'
        next_run_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the next scheduled run is due, in ISO 8601. Always null on
            `manual` and `instant`: one pays out nothing and the other reacts to
            funds settling rather than to a clock, so neither has a next run to
            show.
          example: '2026-08-13T09:00:00.000Z'
        last_run_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When a run last happened, in ISO 8601, whether or not it moved
            money. Null until the first run.
          example: '2026-08-12T09:00:00.000Z'
        last_withdrawal_id:
          type: string
          nullable: true
          description: >-
            The payout created by the last run that moved money. Read it with
            Get Payout. Null until a run has paid out.
          example: pay_4Xr9dLc0mNv7Kq2B
        disabled_reason:
          type: string
          nullable: true
          description: >-
            Why the currency was set back to `manual` by itself, including the
            error from the run that tripped it. Null when that never happened.
          example: >-
            Auto-payout paused after 3 consecutive failures. Last error:
            destination rejected in review
    Error:
      type: object
      description: Standard error response format used across all API endpoints
      properties:
        detail:
          type: string
          description: Human-readable error message explaining what went wrong.
          example: Invalid request parameters
        error_code:
          type: string
          description: >-
            Machine-readable error code. Use this to handle errors
            programmatically. Common codes: VALIDATION_ERROR, UNAUTHORIZED,
            FORBIDDEN, NOT_FOUND, CONFLICT, TOO_MANY_REQUESTS,
            INTERNAL_SERVER_ERROR, BAD_GATEWAY, SERVICE_UNAVAILABLE.
          example: VALIDATION_ERROR
        errors:
          type: array
          description: >-
            Optional array of field-level validation errors. Only present for
            validation errors (400).
          items:
            type: object
            properties:
              field:
                type: string
                description: The field that failed validation.
                example: amount
              message:
                type: string
                description: Description of the validation failure.
                example: Amount must be a positive decimal string
              type:
                type: string
                description: Error type identifier.
                example: value_error
            required:
              - field
              - message
              - type
      required:
        - detail
        - error_code
  responses:
    BadRequest:
      description: >-
        Bad Request - Validation errors or invalid request format. Check the
        `details` object for field-specific validation errors. Common causes:
        missing required fields, invalid data types, values outside allowed
        ranges, or invalid formats.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: Invalid request parameters
            error_code: VALIDATION_ERROR
            errors:
              - field: amount
                message: Amount must be a positive decimal string
                type: value_error
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
    Unauthorized:
      description: >-
        Unauthorized - Invalid, missing, or expired API key. Verify your API key
        is correctly formatted and included in the Authorization header as
        `Bearer sk_sandbox_...` or `Bearer sk_live_...`. Check that your key
        hasn't been revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: Invalid API key
            error_code: UNAUTHORIZED
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
    Forbidden:
      description: >-
        Forbidden - API key does not have permission for the requested resource.
        Verify you're using the correct account's API key and that you're not
        trying to access another account's data.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: API key does not have permission for this operation
            error_code: FORBIDDEN
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
    NotFound:
      description: >-
        Not Found - The requested resource does not exist. Verify the resource
        ID is correct and that it belongs to your account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: Resource not found
            error_code: NOT_FOUND
      headers:
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 100
        X-RateLimit-Remaining:
          description: Number of requests remaining in the current window
          schema:
            type: integer
            example: 95
        X-RateLimit-Reset:
          description: Unix timestamp when the rate limit window resets
          schema:
            type: integer
            example: 1706102400
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Bearer token authentication. Pass your API key as `Authorization: Bearer
        sk_...`. See [Authentication](/authentication) for keys, scopes, and
        sandbox vs production.

````