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

# Refund a charge

> Issue a refund for a successfully paid charge. The refund is created as a new payout linked to the original charge through `related_payments`. The customer receives the funds back at the bank account they paid from. Each charge can be refunded once; partial and full refunds are both supported.



## OpenAPI

````yaml post /v1/charges/{id}/refund
openapi: 3.1.0
info:
  title: Straddle API
  version: v1
  description: >-

    [![Run in
    Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/30656205-137b704d-b21a-408c-a55e-453c2e46d778?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D30656205-137b704d-b21a-408c-a55e-453c2e46d778%26entityType%3Dcollection%26workspaceId%3D7ec8be21-f569-4114-aa8d-4ff6dbde1b0e#?env%5BSandbox%5D=W3sia2V5IjoidG9rZW4iLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWUsInR5cGUiOiJkZWZhdWx0Iiwic2Vzc2lvblZhbHVlIjoiIiwiY29tcGxldGVTZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjB9LHsia2V5IjoiY29sbGVjdGlvbk5hbWUiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWUsInR5cGUiOiJkZWZhdWx0Iiwic2Vzc2lvblZhbHVlIjoiIiwiY29tcGxldGVTZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjF9LHsia2V5IjoiY29sbGVjdGlvblNjaGVtYVVybCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQiLCJzZXNzaW9uVmFsdWUiOiIiLCJjb21wbGV0ZVNlc3Npb25WYWx1ZSI6IiIsInNlc3Npb25JbmRleCI6Mn0seyJrZXkiOiJhY2Nlc3NLZXkiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWUsInR5cGUiOiJkZWZhdWx0Iiwic2Vzc2lvblZhbHVlIjoiIiwiY29tcGxldGVTZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjN9LHsia2V5Ijoid29ya3NwYWNlSWQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWUsInR5cGUiOiJkZWZhdWx0Iiwic2Vzc2lvblZhbHVlIjoiIiwiY29tcGxldGVTZXNzaW9uVmFsdWUiOiIiLCJzZXNzaW9uSW5kZXgiOjR9LHsia2V5IjoiY29sbGVjdGlvbklkIiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoiZGVmYXVsdCIsInNlc3Npb25WYWx1ZSI6IiIsImNvbXBsZXRlU2Vzc2lvblZhbHVlIjoiIiwic2Vzc2lvbkluZGV4Ijo1fSx7ImtleSI6ImJhc2V1cmwiLCJ2YWx1ZSI6InNhbmRib3giLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoiZGVmYXVsdCIsInNlc3Npb25WYWx1ZSI6IiIsImNvbXBsZXRlU2Vzc2lvblZhbHVlIjoiIiwic2Vzc2lvbkluZGV4Ijo2fSx7ImtleSI6ImJlYXJlclRva2VuIiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoic2VjcmV0Iiwic2Vzc2lvblZhbHVlIjoiZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5Sm9kSFJ3T2k4dmMyTm9aVzFoY3k1dGFXTnliM052Wm5RdVkyOXRMM2R6THpJd01EZ3ZNRFl2YVdSbGJuUnBkSGt2WTJ4aGFXMXpMM0p2YkdVaU9pSkJjR2xMWlhraUxDSm8uLi4iLCJjb21wbGV0ZVNlc3Npb25WYWx1ZSI6ImV5SmhiR2NpT2lKSVV6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpvZEhSd09pOHZjMk5vWlcxaGN5NXRhV055YjNOdlpuUXVZMjl0TDNkekx6SXdNRGd2TURZdmFXUmxiblJwZEhrdlkyeGhhVzF6TDNKdmJHVWlPaUpCY0dsTFpYa2lMQ0pvZEhSd09pOHZjMk5vWlcxaGN5NXRhV055YjNOdlpuUXVZMjl0TDNkekx6SXdNRGd2TURZdmFXUmxiblJwZEhrdlkyeGhhVzF6TDJGMWRHaGxiblJwWTJGMGFXOXViV1YwYUc5a0lqb2lVM1J5WVdSa2JHVkJjR2xCZFhSb1RXVjBhRzlrSWl3aWRHOXJaVzVmYVdRaU9pSm1PR0ptT1dVNE15MDFNREUxTFRRMU9UUXRPV1JqTXkwMU5ERm1PR1kwTVdFelpqSWlMQ0psYm5acGNtOXViV1Z1ZENJNkluTmhibVJpYjNnaUxDSm9kSFJ3T2k4dmMyTm9aVzFoY3k1dGFXTnliM052Wm5RdVkyOXRMM2R6THpJd01EZ3ZNRFl2YVdSbGJuUnBkSGt2WTJ4aGFXMXpMMlY0Y0dseVlYUnBiMjRpT2lJeE56TXlPRE00TkRBd0lpd2lhWE56SWpvaWMzUnlZV1JrYkdVaWZRIiwic2Vzc2lvbkluZGV4Ijo3fV0=)
     # Introduction

    Built on REST principles, the Straddle API uses intuitive, resource-oriented
    URLs and communicates via JSON-encoded request bodies and responses. We
    employ standard HTTP methods, authentication, and status codes to ensure
    consistency and predictability.



    # Environments


    Straddle provides two separate environments to support your development
    workflow: the **Sandbox** environment for testing and development, and the
    **Production** environment for live transactions.


    | Environment | Base URL                      | Purpose                 |

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

    | Sandbox     | `https://sandbox.straddle.com` | Testing and development |

    | Production  | `https://production.straddle.com` | Live transactions      
    |


    **Warning:** Always ensure you're using the correct environment and API
    keys. Using Sandbox credentials in Production will cause requests to fail
    and negatively impact the user experience.



    # Authentication


    Straddle uses Bearer Token authentication via JWT API keys. Include your
    secret API key in the `Authorization` header of every request:


    ```bash

    curl https://sandbox.straddle.com/v1/customers \
      -H "Authorization: Bearer YOUR_SECRET_API_KEY"
    ```


    ### Generate an API Key


    Generate an API key from the Straddle Dashboard:


    1. Log in to your [Straddle Dashboard](https://dashboard.straddle.com).

    2. Navigate to **Developers** > **API Keys**.

    3. Click **Create API Key** to generate a new key.


    > **Warning:** Your secret API key grants full access to your Straddle
    account. Keep it secure and **never** share it publicly or include it in
    client-side code.


    ### Sandbox and Production Environments


    Straddle provides separate API keys for sandbox and production environments:


    - **Sandbox API Keys**: Use these keys for development and testing.

    - **Production API Keys**: Use these keys in production when you're ready to
    accept real transactions.


    > **Tip:** Always test your integration thoroughly using sandbox API keys
    before switching to production keys.


    ### Keep your API keys secure


    Follow these guidelines to keep your API keys secure:


    1. **Keep Secret Keys Confidential:** Do not share your secret keys in
    emails, chat messages, or public repositories.

    2. **Use Environment Variables:** Store keys securely using environment
    variables or a secrets management system.

    3. **Rotate Keys Regularly:** Periodically rotate your API keys to reduce
    risk.

    4. **Monitor Usage:** Regularly review your API logs in the Dashboard for
    any suspicious activity.


    With authentication and environments configured, you can start making
    requests to Straddle's API. Keep reading to learn more. 



    # Idempotent Requests


    Straddle supports idempotent API requests, which means you can safely retry
    requests without fear of performing the same operation multiple times. This
    is especially important for operations that change state, like creating a
    payment, where duplicate requests could lead to financial discrepancies.


    Idempotency is achieved by including a unique `Idempotency-Key` header in
    your HTTP requests. Straddle uses this key to detect and prevent duplicate
    operations. If a request with a given key has already been successfully
    processed, Straddle will return the original response without re-executing
    the operation.



    ### Request Headers


    To make an idempotent API request, include a unique string in the
    `Idempotency-Key` header. We require a key length of 10-40 characters.


    | Header | Type | Description |

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

    | `Idempotency-Key` | string | A unique identifier for the request. Must be
    10-40 characters long. |


    ### Response Headers


    When an identical request is successfully replayed, the response will
    include the original HTTP status code, original response headers, and the
    original response body, with an additional header:


    | Header | Type | Description |

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

    | `Idempotent-Replayed` | boolean | Set to `true` when the response is a
    replay of a previous successful request. |


    ### Idempotency Error Responses


    The Straddle will return specific error responses in idempotency-related
    scenarios:


    | Status Code | Error Type | Description |

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

    | **400** | Bad Request | The `Idempotency-Key` header is invalid (missing
    or incorrect length). |

    | **409** | Conflict | The idempotency key was already used for a different
    request, or a previous identical request is currently in progress. |


    ### Idempotency Key Reused for Different Request


    If you send a request with an `Idempotency-Key` that was previously used for
    a different request (e.g., different path, method, or request body), you
    will receive a `409 Conflict` error.


    ```json

    {
      "status": 409,
      "type": "/conflict",
      "title": "Conflict",
      "detail": "Idempotency key already used for a different request."
    }

    ```


    ### Concurrent Request in Progress


    If you send a request with an `Idempotency-Key` that is currently being
    processed by another request, you will receive a `409 Conflict` error.


    ```json

    {
      "status": 409,
      "type": "/conflict",
      "title": "Conflict",
      "detail": "Previous identical request currently in progress."
    }

    ```


    ### Invalid Idempotency Key


    If the `Idempotency-Key` header is missing or does not meet the length
    requirements (10-40 characters), a `400 Bad Request` error will be returned.


    ```json

    {
      "status": 400,
      "type": "/bad-request",
      "title": "Bad Request",
      "detail": "The Idempotency-Key header is invalid. It must be between 10 and 40 characters long."
    }

    ```


    ### Best Practices


    1. **Generate Unique Keys per Business Operation**: For each distinct
    business operation you initiate, generate a new and unique
    `Idempotency-Key`. Do not reuse keys across different logical actions.

    2. **Use UUIDs**: Universally Unique Identifiers (UUIDs) are an excellent
    choice for generating idempotency keys due to their high probability of
    uniqueness.

    4. **Handle 409 Conflicts**: Implement logic in your client to properly
    handle `409 Conflict` responses. For "key already used for a different
    request," generate a new key. For "previous identical request currently in
    progress," consider retrying.

    5. **Key Length**: Ensure your `Idempotency-Key` is between 10 and 40
    characters long.

    6. **Avoid Sending Same Key with Different Data**: Never send the same
    `Idempotency-Key` with a different request body, path, or HTTP method. This
    will result in a `409 Conflict` error.


    ### Example Usage


    ```bash

    curl -X POST https://sandbox.straddle.com/v1/charges \

    -H "Authorization: Bearer YOUR_API_KEY" \

    -H "Content-Type: application/json" \

    -H "Idempotency-Key: unique-client-key-7890" \

    -d '{
      "amount": 100.00,
      "currency": "USD"
    }'

    ```


    Idempotency is currently supported for **POST**, **PUT**, **PATCH** and
    **DELETE** requests only, and requires API key authentication. 



    # Response Structure


    The Straddle API provides responses with consistent structure to ensure
    readability and ease of integration. All API responses follow these
    conventions to ensure consistency and ease of integration across different
    client applications.


    - **Field Naming**
      - Use `snake_case` for all field names
      - Use descriptive full words, except common acronyms (e.g., `dob`, `SSN`)
      
    - **Resource IDs**
      - All IDs are UUIDs for cross-system uniqueness and compatibility
      
    - **Response Type (`response_type`)**
      - `"object"`: Single resource response
      - `"array"`: List of resources, typically paginated
      - `"error"`: Error response with details in `error` field
      
    - **Primary Data (`data`)**
      - Contains main response payload
      - Holds resource(s) for `"object"` and `"array"` types
      - For `"error"` type, error details go in `error` field
      
    - **Meta Information (`meta`)**
      - Standard fields:
        - `api_request_id`: Unique request identifier
        - `api_request_timestamp`: ISO 8601 request time (e.g., `"2023-11-07T05:31:56Z"`)
      - Pagination fields (for `"array"` responses):
        - `page_number`: Current page
        - `page_size`: Items per page
        - `total_items`: Total available items
        - `sort_order`: `"asc"` or `"desc"`
        - `sort_by`: Sort field name

    ### Examples


    #### Single-Object Response


    ```json

    {
      "meta": {
        "api_request_id": "3a2b1c4d-0e6f-4a88-9876-123456abcdef",
        "api_request_timestamp": "2023-11-07T05:31:56Z"
      },
      "response_type": "object",
      "data": {
        "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
        "name": "John Doe",
        "email": "john.doe@example.com",
        "dob": "1990-01-01",
        "address": {
          "street": "123 Main St",
          "city": "Springfield",
          "state": "IL",
          "postal_code": "62701"
        }
      }
    }

    ```


    #### Paginated List Response


    ```json

    {
      "meta": {
        "api_request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
        "api_request_timestamp": "2023-11-07T05:31:56Z",
        "page_number": 2,
        "page_size": 50,
        "total_items": 500,
        "sort_order": "asc",
        "sort_by": "name"
      },
      "response_type": "array",
      "data": [
        {
          "id": "c1b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b",
          "name": "John Doe",
          "email": "john.doe@example.com"
        },
        {
          "id": "a9b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b",
          "name": "Steven Martin",
          "email": "steven.martin@example.com"
        }
      ]
    }

    ```


    #### Error Response


    ```json

    {
      "meta": {
        "api_request_id": "f1b1b1b1-1b1b-1b1b-1b1b-1b1b1b1b1b1b"
      },
      "response_type": "error",
      "error": {
        "status": 400,
        "type": "/field_validation",
        "title": "Invalid Input Data",
        "detail": "The request contains invalid field values.",
        "items": [
          {
            "reference": "customer.email",
            "detail": "Email address must be unique."
          }
        ]
      }
    }

    ```


    ### Best Practices for Handling Responses


    1. **Check the `response_type`**: Determine how to parse the response based
    on the `response_type` field.

    2. **Handle Pagination**: Use pagination metadata to navigate through
    paginated data effectively.

    3. **Implement Robust Error Handling**: Examine the `error` object in error
    responses to understand and address issues.

    4. **Log `api_request_id`**: Record the `api_request_id` for each request to
    assist with troubleshooting and support.

    5. **Access Data via `data` Property**: Retrieve the main payload from the
    `data` property for successful responses.

    6. **Synchronize Timestamps**: Use `api_request_timestamp` for event logging
    and synchronization.

    7. **Consistent Parsing Logic**: Apply a consistent parsing strategy across
    all responses for reliability.

    8. **Avoid Sensitive Data in Logs**: When logging responses, ensure that
    sensitive information is excluded to maintain security.


    By adhering to these practices, you can build a robust integration with the
    Straddle API that gracefully handles various response scenarios.



    # Metadata


    Metadata allows you to attach custom key-value pairs to Straddle objects
    like `customers`, `charges`, and `payouts`. Use metadata to store additional
    information important to your business that isn't captured by Straddle's
    standard fields.


    > **Important:** Do not confuse the `metadata` field with the `meta` object.
    The `meta` object contains system-level information about the API request,
    while `metadata` is for custom data you provide.


    ### Adding Metadata


    You can add metadata when creating or updating objects through the Straddle
    API. Here's how:


    #### Adding Metadata When Creating a Customer


    Include a `metadata` object in your request:


    ```json

    {
      "name": "John Doe",
      "type": "individual",
      "email": "john@example.com",
      "address": {
        "address1": "123 Main St",
        "address2": null,
        "type": "residential",
        "city": "Springfield",
        "state": "IL",
        "zip": "62701"
      },
      "phone": "+1234567890",
      "external_id": "CUS-123",
      "device": {
        "ip_address": "192.168.1.1"
      },
      "metadata": {
        "order_id": "6735",
        "customer_group": "premium"
      }
    }

    ```


    ### Tips

    - **Use Consistent Keys:** Establish and follow a consistent naming
    convention for your metadata keys.

    - **Keep It Simple:** Store simple key-value pairs. For complex data, store
    a reference ID in metadata and keep the full data in your own database.

    - **Avoid Sensitive Data:** Do not store sensitive information like credit
    card numbers or social security numbers in metadata.


    ### Limitations


    - Metadata keys and values must be 40 characters or fewer.

    - You can have up to 20 key-value pairs in the `metadata` object.


    # Embedded Accounts


    Platforms building on Embed can make API calls on behalf of their embedded
    accounts, allowing you to perform actions for your users seamlessly. To
    issue requests as an embedded account, include the `Straddle-Account-Id`
    header with the embedded account's ID (prefixed with `acct_`) in each
    request. You can make API calls for your embedded accounts in two ways:


    1. **Server-side**: Use the `Straddle-Account-Id` header with the embedded
    account ID in each request.

    2. **Client-side**: Pass the `Straddle-Account-Id` as an argument when
    initializing the Straddle client library.


    > **Note:** To ensure optimal performance and reliability, Straddle enforces
    rate limits on API endpoints. These limits apply collectively to all
    requests made by your platform, including those made on behalf of embedded
    accounts.


    ### Server-side Requests Using the `Straddle-Account-Id` Header


    When making server-side API calls, include the `Straddle-Account-Id` header
    with the embedded account's ID to execute requests on their behalf.


    #### Example: Creating a Charge


    The following example demonstrates how to create a charge using your
    platform's secret API key and your user's account ID.


    ```bash

    curl --request POST \
      --url https://sandbox.straddle.com/v1/charges \
      --header 'Authorization: Bearer <your-secret-api-key>' \
      --header 'Content-Type: application/json' \
      --header 'Straddle-Account-Id: <uuid>' \
      --data '{
        "paykey": "<string>",
        "description": "<string>",
        "amount": 123,
        "currency": "<string>",
        "payment_date": "2023-12-25",
        "consent_type": "internet",
        "device": {
          "ip_address": "<string>"
        },
        "external_id": "<string>",
        "config": {
          "balance_check": "required"
        },
        "metadata": {}
      }'
    ```


    ### Client-side Requests


    To make client-side API calls on behalf of an embedded account, pass the
    embedded account ID when initializing the Straddle client. This feature is
    *coming soon*.


    > **Warning:** Exercise caution when making client-side requests as an
    embedded account. Ensure you are not exposing sensitive information or
    providing unnecessary permissions to the client.



    # Errors


    Straddle uses standard HTTP status codes to indicate the success or failure
    of API requests. Understanding these codes and how to handle errors will
    help you build robust and user-friendly applications.


    Here is a summary of the HTTP status and error codes that Straddle may
    return:


    | Status Code | Type | Description |

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

    | **200** | OK | The request was successful, and the response contains the
    expected data. |

    | **400** | Bad Request | The request was invalid, often due to missing or
    incorrect parameters. |

    | **401** | Unauthorized | No valid API key was provided with the request. |

    | **403** | Forbidden | The API key doesn't have the necessary permissions
    to perform the request. |

    | **404** | Not Found | The requested resource does not exist. |

    | **409** | Conflict | The request conflicts with another request (e.g.,
    using the same idempotency key). |

    | **422** | Unprocessable Entity | The request was well-formed but could not
    be processed due to semantic errors. |

    | **429** | Too Many Requests | Too many requests have been made in a short
    period of time. Implement exponential backoff and retry later. |

    | **500, 502, 503, 504** | Server Errors | Server errors—something went
    wrong on Straddle's end. These errors are rare. |


    | Error Type | Description |

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

    | `invalid_request_error` | Occurs when the request has invalid parameters,
    such as missing required fields or invalid values. |

    | `validation_error` | Occurs when the request data fails Straddle's
    validation checks, like providing an invalid address or unsupported payment
    method. |

    | `authentication_error` | Occurs when the provided API key is invalid or
    lacks the necessary permissions for the requested action. |

    | `api_error` | Covers any other type of problem, such as temporary issues
    with Straddle's servers. These errors are rare. |


    When an error occurs, Straddle returns an HTTP response with the appropriate
    status code and a JSON body containing an `error` object with details about
    the error.


    ### Error Response Structure


    When an error occurs, Straddle returns an HTTP response with the appropriate
    status code and a JSON body containing an `error` object with details about
    the error.


    The `error` object includes the following attributes:


    | Attribute | Type | Description |

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

    | `status` | integer | The HTTP status code returned. |

    | `type` | string | A string identifying the type of error. Possible values
    are `api_error`, `invalid_request_error`, `validation_error`, or
    `authentication_error`. |

    | `title` | string | A short description of the error type. |

    | `detail` | string | A detailed message about the error. |

    | `items` | array | (Optional) An array of objects providing more specific
    details about individual errors. |

    | `items[].reference` | string | An identifier related to the error, such as
    a field name or error code. |

    | `items[].detail` | string | A detailed description of the specific error.
    |


    ### Example Error Response


    Here's an example of a validation error response:


    ```json

    {
      "meta": {
        "api_request_id": "3a2b1c4d-0e6f-4a88-9876-123456abcdef",
        "api_request_timestamp": "2023-11-07T05:31:56Z"
      },
      "response_type": "error",
      "error": {
        "status": 400,
        "type": "validation_error",
        "title": "Invalid Input Data",
        "detail": "The request contains invalid field values.",
        "items": [
          {
            "reference": "customer.email",
            "detail": "Email address must be unique."
          }
        ]
      }
    }

    ```


    - The error type is `validation_error`, indicating issues with the input
    data.

    - The `items` array provides specific details about which field caused the
    error. 

    # 
servers:
  - url: https://{environment}.straddle.com
    description: Straddle API server
    variables:
      environment:
        default: sandbox
        enum:
          - production
          - sandbox
        description: >-
          API environment for testing (sandbox) or live transactions
          (production)
security:
  - Bearer: []
tags:
  - name: Customers
    description: >-
      Customers represent the end users who send or receive payments through
      your integration. Each customer undergoes automatic identity verification
      and fraud screening upon creation. Use customers to track payment history,
      manage bank account connections, and maintain a secure record of all
      transactions associated with a user. Customers can be either individuals
      or businesses with appropriate compliance checks for each type.
  - name: Bridge
    description: >-
      Bridge provides a comprehensive suite of tools for connecting customer
      bank accounts. Use it to generate secure widget sessions for instant
      account verification, accept tokens from major providers like Plaid and
      Finicity, or verify accounts directly via our API. Bridge handles all
      sensitive banking credentials and ensures secure, compliant connections
      with support for 90% of US bank accounts.
  - name: Paykeys
    description: >-
      Paykeys are secure tokens that link verified customer identities to their
      bank accounts. Each Paykey includes built-in balance checking, fraud
      detection through LSTM machine learning models, and can be reused for
      subscriptions and recurring payments without storing sensitive data.
      Paykeys eliminate fraud by ensuring the person initiating payment owns the
      funding account.
  - name: Charge
    description: >-
      Charges represent attempts to debit money from a customer's bank account
      using a Paykey. Each charge includes automatic balance verification,
      real-time fraud screening, and multi-rail optimization and detailed status
      tracking throughout the payment lifecycle. Use charges to accept bank
      payments with confidence knowing every transaction is protected.
    x-displayName: Charges
  - name: Payout
    description: >-
      Payouts represent transfers from Straddle to customer bank accounts.
      Create payouts to handle disbursements, process refunds, or manage
      marketplace settlements. Use payouts to send money quickly and securely
      with the most cost-effective rail automatically selected.
    x-displayName: Payouts
  - name: Funding Events
    description: >-
      Funding events represent all money movement between Straddle and an
      Account's external bank accounts. They are automatically generated when
      charges settle or payouts are initiated. Each event provides detailed
      tracking of settlement status, fee breakdowns, and reconciliation data
      across both incoming and outgoing transfers. Use funding events to monitor
      your platform's entire money movement lifecycle.
  - name: Payments
    description: >-
      Payments provide endpoints to filter both Charges and Payouts with
      multiple different parameters.
  - name: Organizations
    description: >-
      Organizations are a powerful feature in Straddle that allow you to manage
      multiple accounts under a single umbrella. This hierarchical structure is
      particularly useful for businesses with complex operations, multiple
      departments, or legally related entities.
  - name: Accounts
    description: >-
      Accounts represent businesses using Straddle through your platform. Each
      account must complete automated verification before processing payments.
      Use accounts to manage your users' payment capabilities, track
      verification status, and control access to features. Accounts can be
      instantly created in sandbox and require additional verification for
      production access.
  - name: Representatives
    description: >-
      Representatives are individuals who have legal authority or significant
      responsibility within a business entity associated with a Straddle
      account. Each representative undergoes automated verification as part of
      KYC/KYB compliance. Use representatives to collect and verify beneficial
      owners, control persons, and authorized signers required for account
      onboarding. Representatives also determine who can legally operate the
      account and make important changes.
  - name: CapabilityRequests
    description: >-
      Capabilities enable specific features and services for an Account. Use
      capability requests to unlock higher processing limits, new payment types,
      or additional platform features as your users' businesses grow. Track
      approval status and manage documentation requirements through a single
      interface.
    x-displayName: Capabilities
  - name: LinkedBankAccounts
    description: >-
      Linked bank accounts connect your platform users' external bank accounts
      to Straddle for settlements and payment funding. Each linked account
      undergoes automated verification and continuous monitoring. Use linked
      accounts to manage where clients receive deposits, fund payouts, and track
      settlement preferences.
    x-displayName: Linked Bank Accounts
paths:
  /v1/charges/{id}/refund:
    post:
      tags:
        - Charge
      summary: Refund a paid charge.
      description: >-
        Issue a refund for a successfully paid charge. The refund is created as
        a new payout linked to the original charge through `related_payments`.
        The customer receives the funds back at the bank account they paid from.
        Each charge can be refunded once; partial and full refunds are both
        supported.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Straddle-Account-Id
          in: header
          description: >-
            For use by platforms to specify an account id and set scope of a
            request.
          schema:
            type: string
            format: uuid
        - name: Request-Id
          in: header
          description: Optional client generated identifier to trace and debug a request.
          schema:
            type: string
        - name: Correlation-Id
          in: header
          description: >-
            Optional client generated identifier to trace and debug a series of
            requests.
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          description: Optional client generated value to use for idempotent requests.
          schema:
            maxLength: 40
            minLength: 10
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefundChargeV1Request'
          text/json:
            schema:
              $ref: '#/components/schemas/RefundChargeV1Request'
          application/*+json:
            schema:
              $ref: '#/components/schemas/RefundChargeV1Request'
      responses:
        '201':
          description: Created
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/PayoutV1ItemResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/PayoutV1ItemResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/PayoutV1ItemResponse'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation Failed
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Server Error
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-codeSamples:
        - lang: cURL
          source: |-
            curl --request POST \
              --header 'Authorization: Bearer YOUR_SECRET_API_KEY' \
              --url https://sandbox.straddle.com/v1/charges/<uuid>/refund \
              --header 'Content-Type: application/json' \
              --data '{
              "amount": 5000
            }'
components:
  schemas:
    RefundChargeV1Request:
      required:
        - amount
      type: object
      properties:
        amount:
          type: integer
          description: >-
            The refund amount in cents. Must be greater than 0 and no more than
            the original charge amount.
          format: int32
          example: 5000
          nullable: true
        description:
          type: string
          description: >-
            Optional reason recorded on the refund payout. Appended to the
            system-generated description `Refund for Charge ID: {id}`.
          nullable: true
        external_id:
          type: string
          description: >-
            Optional unique identifier for this refund, used to correlate with
            your internal records. Defaults to a new value if not specified.
          nullable: true
        payment_date:
          type: string
          description: >-
            The date on which to submit the refund for processing. Defaults to
            today if not specified.
          format: date
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Optional key-value pairs for storing additional structured data.
            Keys and values must be strings.
          nullable: true
      additionalProperties: false
    PayoutV1ItemResponse:
      required:
        - data
        - response_type
        - meta
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/ResponseMetadata'
        response_type:
          $ref: '#/components/schemas/ResponseTypeEnum'
        data:
          $ref: '#/components/schemas/PayoutV1'
      additionalProperties: false
    ErrorResponse:
      required:
        - error
        - response_type
        - meta
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/ResponseMetadata'
        response_type:
          $ref: '#/components/schemas/ResponseTypeEnum'
        error:
          $ref: '#/components/schemas/ErrorContent'
      additionalProperties: false
    ResponseMetadata:
      required:
        - api_request_id
        - api_request_timestamp
      type: object
      description: Metadata about the API request, including an identifier and timestamp.
      properties:
        api_request_id:
          type: string
          description: Unique identifier for this API request, useful for troubleshooting.
          format: uuid
        api_request_timestamp:
          type: string
          description: Timestamp for this API request, useful for troubleshooting.
          format: date-time
      additionalProperties: false
    ResponseTypeEnum:
      enum:
        - object
        - array
        - error
        - none
      type: string
      description: >-
        Indicates the structure of the returned content.

        - "object" means the `data` field contains a single JSON object.

        - "array" means the `data` field contains an array of objects.

        - "error" means the `data` field contains an error object with details
        of the issue.

        - "none" means no data is returned.
    PayoutV1:
      required:
        - config
        - currency
        - status
        - status_history
        - device
        - id
        - paykey
        - status_details
        - amount
        - description
        - payment_date
        - external_id
        - funding_ids
        - trace_ids
        - has_resubmit
        - is_refund
        - is_resubmit
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the payout.
          format: uuid
        paykey:
          type: string
          description: Value of the `paykey` used for the payout.
        description:
          type: string
          description: An arbitrary description for the payout.
          nullable: true
        payment_rail:
          $ref: '#/components/schemas/PaymentRailV1'
          description: The payment rail used for the payout.
        customer_details:
          $ref: '#/components/schemas/CustomerDetailsV1'
          description: Information about the customer associated with the payout.
        paykey_details:
          $ref: '#/components/schemas/PaykeyDetailsV1'
          description: Information about the paykey used for the payout.
        amount:
          type: integer
          description: The amount of the payout in cents.
          format: int32
          example: '10000'
        currency:
          type: string
          description: The currency of the payout. Only USD is supported.
          default: USD
        payment_date:
          type: string
          description: >-
            The desired date on which the payment should be occur. For payouts,
            this means the date you want the funds to be sent from your bank
            account.
          format: date
        device:
          $ref: '#/components/schemas/DeviceInfoV1'
          description: >-
            Information about the device used when the customer authorized the
            payout.
        external_id:
          type: string
          description: >-
            Unique identifier for the payout in your database. This value must
            be unique across all payouts.
        config:
          $ref: '#/components/schemas/PayoutConfigurationV1'
          description: Configuration for the payout.
        created_at:
          type: string
          description: The time the payout was created.
          format: date-time
          nullable: true
        updated_at:
          type: string
          description: The time the payout was last updated.
          format: date-time
          nullable: true
        processed_at:
          type: string
          description: >-
            The time the payout was processed by Straddle and originated to the
            payment rail.
          format: date-time
          nullable: true
        effective_at:
          type: string
          description: >-
            The actual date on which the payment occurred. For payouts, this is
            the date the funds were sent from your bank account.
          format: date-time
          nullable: true
        status:
          $ref: '#/components/schemas/PaymentStatusV1'
          description: The current status of the payout.
          example: created
        status_details:
          $ref: '#/components/schemas/StatusDetailsV11'
          description: Details about the current status of the payout.
        status_history:
          type: array
          items:
            $ref: '#/components/schemas/StatusHistoryV1'
          description: History of the status changes for the payout.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Up to 20 additional user-defined key-value pairs. Useful for storing
            additional information about the payout in a structured format.
          nullable: true
        funding_ids:
          type: array
          items:
            type: string
            format: uuid
          description: Funding Ids
        trace_ids:
          type: object
          additionalProperties:
            type: string
          description: Trace Ids.
        related_payments:
          type: array
          items:
            $ref: '#/components/schemas/RelatedPaymentV1'
          description: Related payments.
          nullable: true
        is_refund:
          type: boolean
          description: Is the payout a refund of an original charge.
        is_resubmit:
          type: boolean
          description: Is the payout a resubmit of an original payout.
        has_resubmit:
          type: boolean
          description: Has the payout been resubmitted.
      additionalProperties: false
    ErrorContent:
      required:
        - type
        - status
        - title
      type: object
      properties:
        status:
          type: integer
          description: HTTP status code for the error.
          format: int32
        type:
          type: string
          description: Predefined general type of error (e.g. '/field_validation')
        title:
          type: string
          description: Generic message for this type of issue.
        detail:
          type: string
          description: Specific message regarding this exact request.
          nullable: true
        items:
          type: array
          items:
            $ref: '#/components/schemas/ErrorItem'
          description: Array of error objects with more specific details.
          nullable: true
      additionalProperties: false
    PaymentRailV1:
      enum:
        - ach
      type: string
      description: The payment rail used for the charge or payout.
    CustomerDetailsV1:
      required:
        - name
        - phone
        - id
        - email
        - customer_type
      type: object
      description: Information about the customer associated with the charge or payout.
      properties:
        id:
          type: string
          description: Unique identifier for the customer
          format: uuid
        name:
          type: string
          description: The name of the customer
          example: Ron Swanson
        customer_type:
          $ref: '#/components/schemas/CustomerTypeV11'
          description: The type of customer
        email:
          type: string
          description: The customer's email address
          example: ron@swanson.com
        phone:
          type: string
          description: The customer's phone number in E.164 format
          example: '+1234567890'
      additionalProperties: false
    PaykeyDetailsV1:
      required:
        - id
        - label
        - customer_id
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the paykey.
          format: uuid
        customer_id:
          type: string
          description: Unique identifier for the customer associated with the paykey.
          format: uuid
        label:
          type: string
          description: >-
            Human-readable label that combines the bank name and masked account
            number to help easility represent this paykey in a UI
          example: Bank of America ****1234
        balance:
          type: integer
          description: >-
            The most recent balance of the bank account associated with the
            paykey in dollars.
          format: int32
          nullable: true
          example: '100.00'
      additionalProperties: false
    DeviceInfoV1:
      required:
        - ip_address
      type: object
      properties:
        ip_address:
          type: string
          description: >-
            The IP address of the device used when the customer authorized the
            charge or payout. Use `0.0.0.0` to represent an offline consent
            interaction.
          format: ipv4
          example: 192.168.1.1
      additionalProperties: false
    PayoutConfigurationV1:
      type: object
      additionalProperties: false
      properties:
        sandbox_outcome:
          $ref: '#/components/schemas/SandboxPaymentOutcomeV1'
        auto_hold:
          type: boolean
          description: >-
            Defines whether to automatically place this charge on hold after
            being created.
          nullable: true
        auto_hold_message:
          type: string
          description: The reason the payout is being automatically held on creation.
          nullable: true
    PaymentStatusV1:
      enum:
        - created
        - scheduled
        - failed
        - cancelled
        - on_hold
        - pending
        - paid
        - reversed
        - validating
      type: string
      description: The current status of the `charge` or `payout`.
      default: created
    StatusDetailsV11:
      required:
        - message
        - changed_at
        - reason
        - source
      type: object
      properties:
        message:
          type: string
          description: A human-readable description of the current status.
          example: Payment successfully created and awaiting validation.
        reason:
          $ref: '#/components/schemas/StatusReasonV1'
          description: >-
            A machine-readable identifier for the specific status, useful for
            programmatic handling.
          example: OK
        source:
          $ref: '#/components/schemas/StatusSourceV1'
          description: >-
            Identifies the origin of the status change (e.g., `bank_decline`,
            `watchtower`). This helps in tracking the cause of status updates.
          example: system
        changed_at:
          type: string
          description: The time the status change occurred.
          format: date-time
        code:
          type: string
          description: The status code if applicable.
          nullable: true
          example: null
      additionalProperties: false
    StatusHistoryV1:
      required:
        - status
        - message
        - source
        - changed_at
        - reason
      type: object
      properties:
        reason:
          $ref: '#/components/schemas/StatusReasonV1'
          description: >-
            A machine-readable identifier for the specific status, useful for
            programmatic handling.
        source:
          $ref: '#/components/schemas/StatusSourceV1'
          description: >-
            Identifies the origin of the status change (e.g., `bank_decline`,
            `watchtower`). This helps in tracking the cause of status updates.
        message:
          type: string
          description: A human-readable description of the status.
          example: Payment successfully created and awaiting validation.
        code:
          type: string
          description: The status code if applicable.
          nullable: true
          example: null
        changed_at:
          type: string
          description: The time the status change occurred.
          format: date-time
        status:
          $ref: '#/components/schemas/PaymentStatusV1'
      additionalProperties: false
    RelatedPaymentV1:
      required:
        - id
        - relationship
        - payment_type
      type: object
      properties:
        id:
          type: string
          description: The ID of the related payment.
          format: uuid
        relationship:
          $ref: '#/components/schemas/RelatedPaymentTypeV1'
        payment_type:
          $ref: '#/components/schemas/PaymentTypeV1'
      additionalProperties: false
    ErrorItem:
      required:
        - detail
      type: object
      properties:
        reference:
          type: string
          description: Identifier for the error (e.g., field name, error code).
          nullable: true
        detail:
          type: string
          description: Detailed description of the specific error.
      additionalProperties: false
    CustomerTypeV11:
      enum:
        - individual
        - business
      type: string
    SandboxPaymentOutcomeV1:
      enum:
        - standard
        - paid
        - on_hold_daily_limit
        - cancelled_for_fraud_risk
        - cancelled_for_balance_check
        - failed_insufficient_funds
        - reversed_insufficient_funds
        - failed_customer_dispute
        - reversed_customer_dispute
        - failed_closed_bank_account
        - reversed_closed_bank_account
      type: string
      description: Payment will simulate processing if not Standard.
    StatusReasonV1:
      enum:
        - insufficient_funds
        - closed_bank_account
        - invalid_bank_account
        - invalid_routing
        - disputed
        - payment_stopped
        - owner_deceased
        - frozen_bank_account
        - risk_review
        - fraudulent
        - duplicate_entry
        - invalid_paykey
        - payment_blocked
        - amount_too_large
        - too_many_attempts
        - internal_system_error
        - user_request
        - ok
        - other_network_return
        - payout_refused
        - cancel_request
        - failed_verification
        - require_review
        - blocked_by_system
        - watchtower_review
        - validating
        - auto_hold
      type: string
    StatusSourceV1:
      enum:
        - watchtower
        - bank_decline
        - customer_dispute
        - user_action
        - system
      type: string
    RelatedPaymentTypeV1:
      enum:
        - original
        - resubmit
        - refund
      type: string
    PaymentTypeV1:
      enum:
        - charge
        - payout
      type: string
      description: The type of payment.
  securitySchemes:
    Bearer:
      type: http
      description: >-
        Use your Straddle API Key in the Authorization header as Bearer <token>
        to authorize API requests.
      scheme: bearer
      bearerFormat: JWT

````