{
  "openapi": "3.1.0",
  "info": {
    "title": "Entendre API",
    "version": "1.0.0",
    "description": "Programmatic access to crypto-native accounting and treasury operations."
  },
  "servers": [
    {
      "url": "https://api.entendre.finance",
      "description": "Production API."
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Organization",
      "description": "Read your organization profile and find members for agent assignments."
    },
    {
      "name": "Transactions",
      "description": "Find transactions, inspect their details and create manual records."
    },
    {
      "name": "Sources",
      "description": "Manage wallets, exchange accounts, bank accounts and other transaction sources."
    },
    {
      "name": "Assets",
      "description": "Inspect asset acquisitions, remaining quantities and cost basis."
    },
    {
      "name": "Journals",
      "description": "Create and post journal entries, correct eligible entries and sync posted journals to a connected general ledger."
    },
    {
      "name": "Documents",
      "description": "Upload documents, check processing status and link supporting evidence to transactions."
    },
    {
      "name": "Legal Entities",
      "description": "Manage the legal entities used in your accounting records."
    },
    {
      "name": "Ledger Accounts",
      "description": "Manage your chart of accounts and find accounts for journal entries."
    },
    {
      "name": "Tags",
      "description": "Create and manage tags to classify your records."
    },
    {
      "name": "Accruals",
      "description": "Create and post accruals, inspect their status and reverse eligible entries."
    },
    {
      "name": "Cash Application",
      "description": "Match deposits to invoices and manage the resulting cash applications."
    },
    {
      "name": "Classification",
      "description": "Classify transactions in a batch, post eligible entries and inspect the results."
    },
    {
      "name": "Revaluation",
      "description": "Run asset revaluations for an accounting period and check their results."
    },
    {
      "name": "Accounting Periods",
      "description": "Check whether a period is ready to close, then close or reopen it."
    },
    {
      "name": "Income Statement",
      "description": "View revenue, expenses and net income for a reporting period."
    },
    {
      "name": "Balance Sheet",
      "description": "View assets, liabilities and equity as of a reporting date."
    },
    {
      "name": "Trial Balance",
      "description": "Review ledger account balances and debit and credit totals."
    },
    {
      "name": "Closing Positions",
      "description": "View asset positions at the end of a reporting period."
    },
    {
      "name": "Treasury Balances",
      "description": "Review treasury balances by asset and source."
    },
    {
      "name": "Realized Gains & Losses",
      "description": "Review realized gains and losses from asset dispositions."
    },
    {
      "name": "Asset Tax Lots",
      "description": "Inspect asset tax lots, remaining quantities and cost basis."
    },
    {
      "name": "Schedule of Dispositions",
      "description": "Review asset dispositions and their proceeds, cost basis and gains or losses."
    },
    {
      "name": "Financial Insights",
      "description": "Review financial insights for your selected reporting context."
    },
    {
      "name": "Agents",
      "description": "Create agents, schedule their work and inspect their runs."
    },
    {
      "name": "Memory",
      "description": "Read, search and maintain the memory files your agents use."
    },
    {
      "name": "Connections",
      "description": "Connect providers, manage authorization and disconnect."
    },
    {
      "name": "GL Mapping",
      "description": "Map ledger accounts and legal entities to your ERP. Import legal entities, tags and chart of accounts."
    },
    {
      "name": "Request",
      "description": "Request information, documents or connections from a client."
    },
    {
      "name": "Client",
      "description": "Manage your firm’s client relationships."
    },
    {
      "name": "Team",
      "description": "Invite team members and manage their access to your firm."
    },
    {
      "name": "Settings",
      "description": "Read and update your firm settings."
    }
  ],
  "paths": {
    "/v1/organization": {
      "get": {
        "operationId": "get_organization",
        "summary": "Get organization",
        "description": "Returns organization identity, timezone and profile settings. Reporting currency is set on each legal entity.",
        "tags": ["Organization"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OrganizationFull"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "org_abc123",
                    "name": "Example Organization",
                    "web_address": null,
                    "timezone": "UTC",
                    "time_format": "hr12",
                    "onboarding_status": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": null,
                    "logo_url": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "patch": {
        "operationId": "update_organization",
        "summary": "Update organization",
        "description": "Update organization profile fields. Changing the timezone also adjusts accounting-period boundaries.",
        "tags": ["Organization"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OrganizationFull"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "org_abc123",
                    "name": "Example Organization",
                    "web_address": null,
                    "timezone": "UTC",
                    "time_format": "hr12",
                    "onboarding_status": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": null,
                    "logo_url": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "minProperties": 1,
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Organization display name."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone identifier."
                  },
                  "time_format": {
                    "type": "string",
                    "enum": ["hr12", "hr24"],
                    "description": "Clock format for display: `hr12` or `hr24`."
                  },
                  "web_address": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Organization website URL."
                  },
                  "logo_url": {
                    "type": ["string", "null"],
                    "maxLength": 2048,
                    "description": "Logo URL. Pass `null` or an empty string to clear the logo."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Example Company",
                "timezone": "UTC",
                "time_format": "hr12",
                "web_address": "https://example.com",
                "logo_url": null
              }
            }
          }
        }
      }
    },
    "/v1/organization/members": {
      "get": {
        "operationId": "list_organization_members",
        "summary": "List organization members",
        "description": "Lists organization members who can be assigned as agent owners or reviewers, with their IDs, names and roles.",
        "tags": ["Organization"],
        "parameters": [
          {
            "name": "include_pii",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Set to `true` to return full email addresses. Defaults to `false`, which masks them as `a***@example.com`."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by membership status.",
            "schema": {
              "type": "string",
              "enum": ["accepted", "pending"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OrganizationMember"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "mbr_abc123",
                      "user_id": "usr_507f1f77bcf86cd799439011",
                      "name": "Example Accountant",
                      "role": "admin",
                      "status": "accepted",
                      "created_at": null,
                      "updated_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      }
    },
    "/v1/transactions": {
      "get": {
        "operationId": "list_transactions",
        "summary": "List transactions",
        "description": "Lists transactions with resolved vendor names and accounting references. Pass one ID in `transaction_ids` to retrieve one record. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.\n\nSet `include_spam=true` to include spam. ID lookups cannot be combined with `has_posted_journal_entry` or `status=posted/pending`.",
        "tags": ["Transactions"],
        "parameters": [
          {
            "name": "source_class",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["crypto", "fiat", "exchange", "card", "other"]
            },
            "description": "Filter by source class."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["pending", "posted", "spam"]
            },
            "description": "Filter by transaction status."
          },
          {
            "name": "has_posted_journal_entry",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter by whether the transaction has a posted journal entry."
          },
          {
            "name": "include_spam",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Set to `true` to include spam transactions. Use `status=spam` for spam only."
          },
          {
            "name": "min_value",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
              "example": "100.00"
            },
            "description": "Minimum gross fiat value in the selected currency. No currency conversion is applied."
          },
          {
            "name": "max_value",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
              "example": "100.00"
            },
            "description": "Maximum gross fiat value in the selected currency. No currency conversion is applied."
          },
          {
            "name": "min_quantity",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
              "example": "0.5"
            },
            "description": "Minimum gross asset quantity. For fiat transactions, this is the fiat amount."
          },
          {
            "name": "max_quantity",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
              "example": "0.5"
            },
            "description": "Maximum gross asset quantity. For fiat transactions, this is the fiat amount."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "transaction_date",
                "created_at",
                "updated_at",
                "gross_amount",
                "net_amount",
                "gross_price",
                "asset_type",
                "chain"
              ],
              "default": "transaction_date"
            },
            "description": "Field to sort results by."
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            },
            "description": "Sort order. Defaults to descending (newest first)."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          },
          {
            "name": "transaction_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "IDs to return, separated by commas. The other filters also apply. Do not combine with `has_posted_journal_entry`, `status=posted` or `status=pending`."
          },
          {
            "name": "exclude_transaction_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Exclude these transaction IDs. Can be combined with has_posted_journal_entry=false."
          },
          {
            "name": "transaction_sequence_numbers",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^OT-\\d+$",
                "maxLength": 64
              },
              "maxItems": 100
            },
            "style": "form",
            "explode": true,
            "description": "Any of these transaction sequence numbers, such as OT-123. Do not combine with has_posted_journal_entry=false."
          },
          {
            "name": "financial_account_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by IDs returned in account_id. Matches a source or its associated wallet, including linked Solana staking accounts."
          },
          {
            "name": "transaction_types",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "DEPOSIT",
                  "WITHDRAWAL",
                  "SWAP",
                  "NON_TAXABLE_CONVERSION",
                  "BRIDGE",
                  "INTERCOMPANY TRANSFER",
                  "INTERNAL TRANSFER",
                  "FEE",
                  "MINTING",
                  "STAKING_REWARD",
                  "VALIDATOR_REWARD",
                  "INVOICE",
                  "BILL",
                  "CLAIM REWARD",
                  "BORROW",
                  "REPAYMENT",
                  "RESERVES CHANGE",
                  "REALIZED_PNL",
                  "INCOME",
                  "EXPENSE",
                  "REFUND",
                  "CHARGEBACK",
                  "NFT",
                  "SPAM",
                  "UNKNOWN"
                ]
              }
            },
            "style": "form",
            "explode": true,
            "description": "Any of these economic transaction types. These are separate from accounting classifications."
          },
          {
            "name": "source_types",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more source types. Repeat the parameter or send a comma-separated list."
          },
          {
            "name": "asset_types",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more asset types. Repeat the parameter or send a comma-separated list."
          },
          {
            "name": "chains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more chains. Repeat the parameter or send a comma-separated list."
          },
          {
            "name": "addresses",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "maxItems": 100
            },
            "style": "form",
            "explode": true,
            "description": "On-chain addresses, up to 100. Matches the from or to address, without case sensitivity. A transaction matches when it touches an address or belongs to a source in `financial_account_ids` or `source_id`. Repeat the parameter or send a comma-separated list."
          },
          {
            "name": "provider_category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Raw category from Ramp or Plaid, matched as a substring without case sensitivity. Values in the array match any; labels joined with `;` in one value must all match."
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails."
          },
          {
            "name": "count_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Return total_count with an empty data array and no next page. Takes precedence over include_count."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "source_id",
            "in": "query",
            "required": false,
            "description": "Source ID (`src_…`).",
            "schema": {
              "type": "string",
              "example": "src_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "description": "Direction of the movement relative to the source.",
            "schema": {
              "type": "string",
              "enum": ["debit", "credit"]
            }
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "description": "Inclusive event timestamp lower bound.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "description": "Inclusive upper bound for the event timestamp.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "updated_since",
            "in": "query",
            "required": false,
            "description": "Inclusive lower bound for the last update time. When you sync changes, deduplicate by `id` and `updated_at`.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Transaction"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true or count_only=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "txn_507f1f77bcf86cd799439011",
                      "account_id": null,
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "source_class": "fiat",
                      "provider": "plaid",
                      "vendor": null,
                      "provider_category": null,
                      "external": {
                        "timestamp": "2026-08-31T12:00:00Z",
                        "description": "Customer deposit",
                        "direction": "credit",
                        "quantity": null,
                        "currency": "USD",
                        "value_fiat": {
                          "gross": "100.00",
                          "fee": "0.00",
                          "net": "100.00",
                          "currency": "USD"
                        }
                      },
                      "crypto": null,
                      "bank": {
                        "bank_name": "Example Bank",
                        "account_last4": "4242",
                        "counterparty_name": "Example Customer"
                      },
                      "card": null,
                      "internal": {
                        "transaction_type": "DEPOSIT",
                        "status": "pending",
                        "memo": null,
                        "journal_entry_id": null
                      },
                      "created_at": null,
                      "updated_at": null,
                      "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_transaction",
        "summary": "Create transaction",
        "description": "Creates a manual transaction using the fields for its type. This records an economic event; it does not transfer funds. A `timestamp` inside an accounting period that is already closed for the legal entity is refused with `422`. Organization ingestion-filter rejections return `422`. A `201` response is returned only after the saved transaction is read back from the database.",
        "tags": ["Transactions"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "txn_507f1f77bcf86cd799439011",
                    "account_id": null,
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "source_class": "fiat",
                    "provider": "plaid",
                    "vendor": null,
                    "provider_category": null,
                    "external": {
                      "timestamp": "2026-08-31T12:00:00Z",
                      "description": "Customer deposit",
                      "direction": "credit",
                      "quantity": null,
                      "currency": "USD",
                      "value_fiat": {
                        "gross": "100.00",
                        "fee": "0.00",
                        "net": "100.00",
                        "currency": "USD"
                      }
                    },
                    "crypto": null,
                    "bank": {
                      "bank_name": "Example Bank",
                      "account_last4": "4242",
                      "counterparty_name": "Example Customer"
                    },
                    "card": null,
                    "internal": {
                      "transaction_type": "DEPOSIT",
                      "status": "pending",
                      "memo": null,
                      "journal_entry_id": null
                    },
                    "created_at": null,
                    "updated_at": null,
                    "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "source_id": {
                    "type": "string",
                    "description": "Source ID (`src_…`).",
                    "example": "src_507f1f77bcf86cd799439011"
                  },
                  "legal_entity_id": {
                    "type": "string",
                    "description": "Legal entity ID (`le_…`).",
                    "example": "le_507f1f77bcf86cd799439011"
                  },
                  "timestamp": {
                    "type": "string",
                    "description": "ISO 8601 UTC timestamp.",
                    "format": "date-time",
                    "example": "2026-08-31T12:00:00Z"
                  },
                  "description": {
                    "type": "string",
                    "description": "Event narrative.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "Customer deposit"
                  },
                  "direction": {
                    "type": "string",
                    "description": "Movement direction relative to the source; not accounting classification.",
                    "enum": ["debit", "credit"]
                  },
                  "currency": {
                    "type": "string",
                    "description": "Fiat currency.",
                    "example": "USD"
                  },
                  "gross": {
                    "type": "string",
                    "description": "Positive gross fiat amount.",
                    "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
                    "example": "100.00"
                  },
                  "fee": {
                    "type": "string",
                    "description": "Non-negative fee amount.",
                    "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
                    "example": "100.00"
                  },
                  "net": {
                    "type": "string",
                    "description": "Net amount, consistent with gross and fee.",
                    "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
                    "example": "100.00"
                  },
                  "transaction_type": {
                    "$ref": "#/components/schemas/TransactionCategory"
                  },
                  "memo": {
                    "type": ["string", "null"],
                    "description": "Optional memo."
                  },
                  "external_reference": {
                    "type": "string",
                    "description": "Client-owned import identifier, unique within source. Must not start with `chain-event:`; that prefix is reserved.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "bank-deposit-2026-09-01"
                  }
                },
                "required": [
                  "source_id",
                  "legal_entity_id",
                  "timestamp",
                  "description",
                  "direction",
                  "currency",
                  "gross",
                  "fee",
                  "net",
                  "external_reference"
                ],
                "additionalProperties": false
              },
              "example": {
                "source_id": "src_507f1f77bcf86cd799439011",
                "legal_entity_id": "le_507f1f77bcf86cd799439011",
                "timestamp": "2026-08-31T12:00:00Z",
                "description": "Customer deposit",
                "direction": "debit",
                "currency": "USD",
                "gross": "100.00",
                "fee": "100.00",
                "net": "100.00",
                "external_reference": "bank-deposit-2026-09-01"
              }
            }
          }
        }
      }
    },
    "/v1/transactions/{transaction_id}": {
      "patch": {
        "operationId": "update_transaction",
        "summary": "Update transaction",
        "description": "Update the memo, transaction type or spam state. Accounting-state and period restrictions apply. Transaction tags are not supported by this operation.",
        "tags": ["Transactions"],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "ID of the transaction.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "txn_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Transaction"
                    },
                    "reconciliation": {
                      "type": "object",
                      "description": "Present only after a spam change. Shows whether the cost-basis reconciliation was queued.",
                      "required": ["queued", "scope", "job_id", "error"],
                      "properties": {
                        "queued": {
                          "type": "boolean",
                          "description": "`true` when the reconciliation job was queued."
                        },
                        "scope": {
                          "type": "string",
                          "enum": ["none", "source_asset", "organization"],
                          "description": "The records that the reconciliation recalculates."
                        },
                        "job_id": {
                          "type": ["string", "null"],
                          "description": "The reconciliation job ID, or `null` when no job was queued."
                        },
                        "error": {
                          "type": ["string", "null"],
                          "description": "Why the reconciliation could not be queued. The spam change is kept."
                        }
                      }
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "txn_507f1f77bcf86cd799439011",
                    "account_id": null,
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "source_class": "fiat",
                    "provider": "plaid",
                    "vendor": null,
                    "provider_category": null,
                    "external": {
                      "timestamp": "2026-08-31T12:00:00Z",
                      "description": "Customer deposit",
                      "direction": "credit",
                      "quantity": null,
                      "currency": "USD",
                      "value_fiat": {
                        "gross": "100.00",
                        "fee": "0.00",
                        "net": "100.00",
                        "currency": "USD"
                      }
                    },
                    "crypto": null,
                    "bank": {
                      "bank_name": "Example Bank",
                      "account_last4": "4242",
                      "counterparty_name": "Example Customer"
                    },
                    "card": null,
                    "internal": {
                      "transaction_type": "DEPOSIT",
                      "status": "pending",
                      "memo": null,
                      "journal_entry_id": null
                    },
                    "created_at": null,
                    "updated_at": null,
                    "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "transaction_type": {
                        "description": "Economic transaction type. This does not classify accounting or create a journal entry. Case-insensitive on input. Pass `null` to clear.",
                        "anyOf": [
                          {
                            "$ref": "#/components/schemas/TransactionCategory"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "category": {
                        "deprecated": true,
                        "description": "Older name for `transaction_type`. Case-insensitive on input. Pass `null` to clear.",
                        "anyOf": [
                          {
                            "$ref": "#/components/schemas/TransactionCategory"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "classification": {
                        "deprecated": true,
                        "description": "Older name for `transaction_type`. Send only one type field. Case-insensitive on input. Pass `null` to clear.",
                        "anyOf": [
                          {
                            "$ref": "#/components/schemas/TransactionCategory"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "memo": {
                        "type": ["string", "null"],
                        "description": "Free-text memo. Pass `null` to clear."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["spam"],
                    "properties": {
                      "spam": {
                        "type": "boolean",
                        "description": "Set or clear the spam flag. This also performs asset cleanup and reconciliation. Send this field separately from memo or transaction-type changes."
                      }
                    }
                  }
                ]
              },
              "example": {
                "transaction_type": "BILL",
                "memo": "Annual infrastructure cost"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_transaction",
        "summary": "Delete transaction",
        "description": "Soft-deletes an eligible unposted transaction. Posted accounting records are preserved.",
        "tags": ["Transactions"],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "ID of the transaction.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "txn_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/sources": {
      "get": {
        "operationId": "list_sources",
        "summary": "List sources",
        "description": "Lists sources across supported providers. Pass one ID in `source_ids` to retrieve one record. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.\n\nSource-type permissions still apply.",
        "tags": ["Sources"],
        "parameters": [
          {
            "name": "legal_entity_ids",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          },
          {
            "name": "source_types",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "exchange",
                  "staking",
                  "niural",
                  "raincard",
                  "ramp_card",
                  "ramp_bank_account",
                  "manual_bank",
                  "wallet",
                  "plaid_account"
                ]
              }
            },
            "description": "Filter by one or more source types. Repeat the parameter or send a comma-separated list."
          },
          {
            "name": "providers",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by provider labels. A provider with no matching source type returns an empty page."
          },
          {
            "name": "source_ids",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "IDs to return, separated by commas. The other filters also apply."
          },
          {
            "name": "addresses",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Wallet addresses, up to 100. Matching ignores case. Returns wallets only."
          },
          {
            "name": "include_count",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails."
          },
          {
            "name": "tag_ids",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Prefixed `tag_` ids. Supported by wallets and exchange sources; a type that cannot filter on tags is excluded from the results when this is set."
          },
          {
            "name": "statuses",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["active", "archived", "pending_setup"]
              }
            },
            "description": "Any of these lifecycle statuses. Source types without a lifecycle status are excluded when this filter is set."
          },
          {
            "name": "chains",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Chain identifiers (such as `eth`). This filter returns wallets only. Other source types are excluded."
          },
          {
            "name": "wallet_types",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["internal", "external"]
              }
            },
            "description": "Wallet types, lowercase. Supported by wallets and Niural sources; every other type is excluded from the results when this is set."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by one source type.",
            "schema": {
              "type": "string",
              "enum": [
                "exchange",
                "staking",
                "niural",
                "raincard",
                "ramp_card",
                "ramp_bank_account",
                "manual_bank",
                "wallet",
                "plaid_account"
              ]
            }
          },
          {
            "name": "group_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Source group ID (`sgp_…`), or `null` for sources in no group. Staking sources cannot be in a group."
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["group"]
            },
            "description": "Related records to include. `group` adds the source group of each source (`null` when it has none) and needs the `read:source-groups` scope."
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Source"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "src_507f1f77bcf86cd799439011",
                      "source_type": "wallet",
                      "organization_id": null,
                      "legal_entity_id": null,
                      "name": "Treasury wallet",
                      "status": "active",
                      "created_at": null,
                      "updated_at": null,
                      "detail": {
                        "address": "0x0000000000000000000000000000000000000001",
                        "chain": "eth",
                        "has_credentials": false,
                        "ledger_account_id": null
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_source",
        "summary": "Create source",
        "description": "Create a wallet, connected account or manual source. With a statement, reuse its existing source or create a manual source, then start importing transactions.",
        "tags": ["Sources"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "Existing connected source, resolved manual account, or synchronous statement-import result.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Source"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "imported": {
                              "type": "integer",
                              "description": "Transactions imported."
                            },
                            "duplicates": {
                              "type": "integer",
                              "description": "Rows skipped as duplicates."
                            },
                            "errors": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Rows that could not be imported."
                            }
                          },
                          "description": "The created source."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "src_507f1f77bcf86cd799439011",
                    "source_type": "manual_bank",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "name": "Operating account",
                    "status": "active",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "detail": {
                      "account_name": "Operating account",
                      "has_credentials": false,
                      "ledger_account_id": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "201": {
            "description": "Source created. Includes an import when a statement was supplied.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Source"
                    },
                    "import": {
                      "anyOf": [
                        {
                          "$ref": "#/components/schemas/SourceImport"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Accepted statement import when document_id was supplied; null for source creation without a statement."
                    }
                  },
                  "required": ["data", "import"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "src_507f1f77bcf86cd799439011",
                    "source_type": "manual_bank",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "name": "Operating account",
                    "status": "active",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "detail": {
                      "account_name": "Operating account",
                      "has_credentials": false,
                      "ledger_account_id": null
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Import job queued (asynchronous).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": ["string", "null"],
                          "description": "Import job ID, or `null` for a synchronous import."
                        },
                        "message": {
                          "type": "string",
                          "description": "Summary message."
                        }
                      },
                      "description": "The created source."
                    }
                  }
                },
                "example": {
                  "data": {
                    "job_id": "job_wallet-sync:realtime:507f1f77bcf86cd799439011",
                    "message": "Import queued"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": ["source_type", "name", "chain", "address"],
                    "additionalProperties": false,
                    "properties": {
                      "source_type": {
                        "type": "string",
                        "enum": ["wallet"],
                        "description": "The kind of source to create."
                      },
                      "name": {
                        "type": "string",
                        "description": "Display name for the source."
                      },
                      "chain": {
                        "type": "string",
                        "description": "On-chain network for a wallet source (such as `eth`)."
                      },
                      "address": {
                        "type": "string",
                        "description": "On-chain address for a wallet source."
                      },
                      "wallet_type": {
                        "type": "string",
                        "enum": ["internal", "external"],
                        "default": "external",
                        "description": "Internal wallets require a legal entity."
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Legal entity (`le_` prefix). Required for internal wallets."
                      },
                      "tag_ids": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Tag IDs (`tag_…`)."
                      },
                      "allow_nft_import": {
                        "type": "boolean",
                        "description": "Wallet only; every other type ignores it."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": ["name", "chain", "address", "type"],
                    "additionalProperties": false,
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "Display name for the source."
                      },
                      "chain": {
                        "type": "string",
                        "description": "On-chain network for a wallet source (such as `eth`)."
                      },
                      "address": {
                        "type": "string",
                        "description": "On-chain address for a wallet source."
                      },
                      "wallet_type": {
                        "type": "string",
                        "enum": ["internal", "external"],
                        "default": "external",
                        "description": "Internal wallets require a legal entity."
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Legal entity (`le_` prefix). Required for internal wallets."
                      },
                      "tag_ids": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Tag IDs (`tag_…`)."
                      },
                      "allow_nft_import": {
                        "type": "boolean",
                        "description": "Wallet only; every other type ignores it."
                      },
                      "type": {
                        "type": "string",
                        "enum": ["wallet"],
                        "description": "Always `wallet`."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "A Niural supplier source. Chain and address are optional; tags are plain labels, not tag ids.",
                    "required": ["type", "name"],
                    "additionalProperties": false,
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": ["niural"],
                        "description": "The kind of source to create."
                      },
                      "name": {
                        "type": "string",
                        "description": "Supplier or vendor name.",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Legal entity ID (`le_…`). Optional; the supplier can stay unassigned.",
                        "example": "le_507f1f77bcf86cd799439011"
                      },
                      "wallet_type": {
                        "type": "string",
                        "enum": ["internal", "external"],
                        "default": "external",
                        "description": "`internal` for a wallet that you own, `external` for a wallet of a third party."
                      },
                      "chain": {
                        "type": "string",
                        "description": "On-chain network, when the supplier is paid on-chain."
                      },
                      "address": {
                        "type": "string",
                        "description": "Payout address, when known.",
                        "minLength": 1,
                        "maxLength": 256
                      },
                      "tags": {
                        "type": "array",
                        "description": "Plain labels stored on the row.",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "maxItems": 50
                      },
                      "group_id": {
                        "type": "string",
                        "description": "Source group (`sgp_` prefix).",
                        "example": "sgp_507f1f77bcf86cd799439011"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["type", "connection_id"],
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": ["exchange", "bank_account", "card"],
                        "description": "Category of the selected source: `exchange` selects an exchange source, `bank_account` a Plaid or Ramp bank account, `card` a Rain or Ramp card. The selected source must match."
                      },
                      "connection_id": {
                        "type": "string",
                        "description": "Connection ID from List connections."
                      },
                      "external_account_id": {
                        "type": "string",
                        "description": "Select a returned source ID or provider account ID; may be omitted only when the active connection has exactly one source of the requested type."
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Optional. Selecting a source never changes its legal entity."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["type", "document_id"],
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": ["exchange", "bank_account", "card"],
                        "description": "Source type."
                      },
                      "document_id": {
                        "type": "string",
                        "description": "Statement document ID (`doc_…`)."
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Legal entity ID (`le_…`)."
                      },
                      "statement_line_ids": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^bkl_[A-Za-z0-9-]+$"
                        },
                        "minItems": 1,
                        "maxItems": 5000,
                        "description": "Statement lines to import. Omit to import all eligible pending lines."
                      }
                    },
                    "dependentRequired": {
                      "statement_line_ids": ["document_id"]
                    }
                  }
                ]
              },
              "examples": {
                "Wallet": {
                  "value": {
                    "name": "Treasury wallet",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "address": "0x0000000000000000000000000000000000000001",
                    "chain": "eth",
                    "type": "wallet"
                  }
                },
                "Source from statement": {
                  "value": {
                    "type": "bank_account",
                    "name": "Operating account",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "document_id": "doc_507f1f77bcf86cd799439011"
                  }
                },
                "Manual account": {
                  "value": {
                    "type": "bank_account",
                    "name": "Operating account",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/sources/{source_id}": {
      "patch": {
        "operationId": "update_source",
        "summary": "Update source",
        "description": "Updates the source name, archive state, legal entity assignment, tags or the ledger account assignment. Omitted fields stay unchanged. Organization ownership, credentials and import identity cannot be changed here.",
        "tags": ["Sources"],
        "parameters": [
          {
            "name": "source_id",
            "in": "path",
            "required": true,
            "description": "ID of the source.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "src_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Source"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "src_507f1f77bcf86cd799439011",
                    "source_type": "wallet",
                    "organization_id": null,
                    "legal_entity_id": null,
                    "name": "Treasury wallet",
                    "status": "active",
                    "created_at": null,
                    "updated_at": null,
                    "detail": {
                      "address": "0x0000000000000000000000000000000000000001",
                      "chain": "eth",
                      "has_credentials": false,
                      "ledger_account_id": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "minProperties": 1,
                "additionalProperties": false,
                "description": "Provide at least one field. Omit a field to leave it unchanged.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Rename wallet, exchange, Plaid, or manual-bank sources. Other source types do not support renaming. An unsupported field returns `422` without applying the update."
                  },
                  "status": {
                    "type": "string",
                    "enum": ["active", "archived"],
                    "description": "Source status. Supported by wallet, exchange, Plaid and manual-bank sources. Other source types have no status and return HTTP 422."
                  },
                  "legal_entity_id": {
                    "type": ["string", "null"],
                    "description": "Prefixed `le_` id, or null to clear."
                  },
                  "ledger_account_id": {
                    "type": ["string", "null"],
                    "description": "Ledger account (`lac_…`). Send `null` to clear it; omit to keep it. Niural sources return HTTP 422."
                  },
                  "tag_ids": {
                    "type": ["array", "null"],
                    "items": {
                      "type": "string"
                    },
                    "description": "Replaces the tags (`tag_…`). `[]` clears them; omit to keep them. You cannot send it with `add_tag_ids` or `remove_tag_ids`. Wallet, exchange, Plaid and manual-bank sources only; other sources return HTTP 422."
                  },
                  "add_tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags to add (`tag_…`). Wallet, exchange, Plaid and manual-bank sources only; other sources return HTTP 422."
                  },
                  "remove_tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags to remove (`tag_…`). Wallet, exchange, Plaid and manual-bank sources only; other sources return HTTP 422."
                  },
                  "allow_nft_import": {
                    "type": "boolean",
                    "description": "Enable or disable NFT import for a wallet. Other source types do not support this field. An unsupported field returns `422` without applying the update."
                  },
                  "group_id": {
                    "type": ["string", "null"],
                    "description": "Prefixed `sgp_` id of a source group, or `null` to remove the source from its group."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_source",
        "summary": "Delete source",
        "description": "Delete a manually created source that is not in use. A source in use returns a conflict with guidance.\n\nFor a Plaid account, this soft-deletes the account and its bank transactions. Journal entries prevent account deletion. Removing the last account also removes the Plaid item. If provider removal succeeds but local cleanup fails, retry the same operation to finish cleanup.",
        "tags": ["Sources"],
        "parameters": [
          {
            "name": "source_id",
            "in": "path",
            "required": true,
            "description": "ID of the source.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "src_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted. Returns the ID of the deleted source.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": ["id", "deleted"],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID of the record."
                        },
                        "deleted": {
                          "type": "boolean",
                          "enum": [true],
                          "description": "Always `true`."
                        }
                      },
                      "description": "The source."
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "wal_507f1f77bcf86cd799439011",
                    "deleted": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/sources/{source_id}/imports": {
      "post": {
        "operationId": "import_transactions_from_source",
        "summary": "Import transactions from source",
        "description": "Refreshes a source or imports older transactions. Omit the body to refresh from the saved cursor. Send `start_date` to import older wallet transactions. HTTP 202 means that the import is queued. No operation reports the import progress.",
        "tags": ["Sources"],
        "parameters": [
          {
            "name": "source_id",
            "in": "path",
            "required": true,
            "description": "ID of the source.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "wal_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted. The import is queued. No operation reports its progress.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SourceImport"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "job_wallet-sync:realtime:507f1f77bcf86cd799439011",
                    "source_id": "wal_507f1f77bcf86cd799439011",
                    "status": "queued"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Exchange sources do not accept `start_date`, or the source type cannot import.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNPROCESSABLE_CONTENT",
                    "message": "A dated backfill was requested for an exchange source, or the source type has no import job.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "501": {
            "description": "Plaid bank accounts import automatically through Plaid webhooks. There is no manual import.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "NOT_IMPLEMENTED",
                    "message": "Import for bank accounts is handled automatically via Plaid webhooks",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start_date": {
                    "type": "string",
                    "description": "Wallet sources only. Import from this date. Omit to import new transactions only.",
                    "format": "date-time",
                    "example": "2026-08-31T12:00:00Z"
                  },
                  "skip_classification": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip automatic classification for this import. Requires start_date."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "examples": {
                "Refresh": {
                  "value": {}
                },
                "Backfill": {
                  "value": {
                    "start_date": "2026-08-01T00:00:00Z"
                  }
                },
                "Backfill without classification": {
                  "value": {
                    "start_date": "2026-08-01T00:00:00Z",
                    "skip_classification": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/assets": {
      "get": {
        "operationId": "list_assets",
        "summary": "List assets",
        "description": "List asset acquisition records and their remaining quantities and cost basis. Filter by asset IDs, asset types or accounting references.",
        "tags": ["Assets"],
        "parameters": [
          {
            "name": "asset_ids",
            "in": "query",
            "required": false,
            "description": "Exact asset IDs. Combine with other filters to narrow the result.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Asset ID returned by this API."
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["ast_abc123"]
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["date_received", "asset_type", "quantity", "cost_basis", "created_at"]
            },
            "description": "Sort field."
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            },
            "description": "Sort direction."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid.",
            "style": "form",
            "explode": true
          },
          {
            "name": "ledger_account_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Prefixed ledger account IDs (`lac_`). Up to 100 IDs.",
            "style": "form",
            "explode": true
          },
          {
            "name": "asset_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by asset type (such as `ETH`, `BTC`).",
            "style": "form",
            "explode": true
          },
          {
            "name": "chains",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by blockchain chain.",
            "style": "form",
            "explode": true
          },
          {
            "name": "start_date",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter assets received on or after this date (ISO 8601)."
          },
          {
            "name": "end_date",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter assets received on or before this date (ISO 8601)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Asset"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "ast_abc123",
                      "asset_type": "ETH",
                      "quantity": "10.5",
                      "remaining_quantity": "8.25",
                      "cost_basis": "15750.00",
                      "currency": "USD",
                      "date_received": null,
                      "chain": null,
                      "legal_entity_id": null,
                      "ledger_account_id": null,
                      "transaction_id": null,
                      "source_id": null,
                      "is_manual": false,
                      "created_at": null,
                      "updated_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_manual_asset",
        "summary": "Create manual asset",
        "description": "Creates a manual opening asset and adjusts its opening balance. Opening-period and reference checks apply.",
        "tags": ["Assets"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Asset"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ast_abc123",
                    "asset_type": "ETH",
                    "quantity": "100.00",
                    "remaining_quantity": "100.00",
                    "cost_basis": "100.00",
                    "currency": "USD",
                    "date_received": null,
                    "chain": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                    "transaction_id": null,
                    "source_id": "src_507f1f77bcf86cd799439011",
                    "is_manual": true,
                    "created_at": null,
                    "updated_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "asset_type",
                  "quantity",
                  "cost_basis",
                  "legal_entity_id",
                  "ledger_account_id",
                  "source_id"
                ],
                "properties": {
                  "asset_type": {
                    "type": "string",
                    "examples": ["ETH"],
                    "description": "Asset type or symbol. To add to an existing type, use the exact `asset_type` from List assets."
                  },
                  "quantity": {
                    "type": "string",
                    "description": "Positive decimal string, such as `\"10.5\"`. JSON numbers are rejected."
                  },
                  "cost_basis": {
                    "type": "string",
                    "description": "Decimal string, such as `\"15750.00\"`. JSON numbers are rejected."
                  },
                  "legal_entity_id": {
                    "type": "string",
                    "description": "Prefixed legal entity ID (`le_`)."
                  },
                  "ledger_account_id": {
                    "type": "string",
                    "description": "Prefixed ledger account ID (`lac_`)."
                  },
                  "date_received": {
                    "type": "string",
                    "format": "date",
                    "description": "Acquisition date (YYYY-MM-DD).",
                    "example": "2026-08-01"
                  },
                  "source_id": {
                    "type": "string",
                    "description": "Wallet, exchange or Plaid source that holds the opening asset (`wal_…`, `exs_…` or `pla_…` from List sources).",
                    "example": "wal_507f1f77bcf86cd799439011"
                  },
                  "currency": {
                    "type": "string",
                    "description": "Defaults to legal entity base currency."
                  },
                  "chain": {
                    "type": "string",
                    "description": "Blockchain network, such as `eth`."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "asset_type": "ETH",
                "quantity": "100.00",
                "cost_basis": "100.00",
                "legal_entity_id": "le_507f1f77bcf86cd799439011",
                "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                "source_id": "wal_507f1f77bcf86cd799439011"
              }
            }
          }
        }
      }
    },
    "/v1/assets/{asset_id}": {
      "patch": {
        "operationId": "update_manual_asset",
        "summary": "Update manual asset",
        "description": "Update a manual asset and adjust its balances. Imported assets cannot be edited.",
        "tags": ["Assets"],
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "description": "ID of the asset.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ast_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Asset"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ast_abc123",
                    "asset_type": "ETH",
                    "quantity": "100.00",
                    "remaining_quantity": "100.00",
                    "cost_basis": "100.00",
                    "currency": "USD",
                    "date_received": null,
                    "chain": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                    "transaction_id": null,
                    "source_id": null,
                    "is_manual": true,
                    "created_at": null,
                    "updated_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ledger_account_id": {
                    "type": "string",
                    "description": "Ledger account ID (`lac_…`)."
                  },
                  "cost_basis": {
                    "type": "string",
                    "description": "Decimal string, such as `\"18750.00\"`. JSON numbers are rejected."
                  },
                  "quantity": {
                    "type": "string",
                    "description": "Positive decimal string, such as `\"12.5\"`. JSON numbers are rejected."
                  },
                  "legal_entity_id": {
                    "type": "string",
                    "description": "Legal entity ID (`le_…`)."
                  }
                },
                "minProperties": 1,
                "additionalProperties": false
              },
              "example": {
                "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                "cost_basis": "100.00",
                "quantity": "100.00",
                "legal_entity_id": "le_507f1f77bcf86cd799439011"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_manual_asset",
        "summary": "Delete manual asset",
        "description": "Delete an eligible manual asset and adjust its balances. Imported assets cannot be deleted.",
        "tags": ["Assets"],
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "description": "ID of the asset.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ast_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/journal-entries": {
      "get": {
        "operationId": "list_journals",
        "summary": "List journals",
        "description": "Lists journals with their complete lines and ledger account details. Pass one ID in `journal_entry_ids` to retrieve one record. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "statuses",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["draft", "posted", "reversed", "unposted", "in_progress", "error"]
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated journal statuses: `draft`, `posted`, `reversed`, `in_progress`, `error` or `unposted`. A reversed journal has status `reversed`, not `posted`."
          },
          {
            "name": "start_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive lower bound on `accounting_date`. Accepts a date (`2026-08-01`, meaning midnight UTC) or a full timestamp."
          },
          {
            "name": "end_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive accounting-date upper bound. A date includes the whole UTC day; a timestamp includes that exact instant."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["accounting_date", "created_at", "updated_at"]
            },
            "description": "Field to sort by. Use created_at for issuance order; sequence numbers are not a sort option."
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            },
            "description": "Sort direction. Defaults to `desc` (newest first)."
          },
          {
            "name": "originated_by",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\s*(system|user)\\s*(,\\s*(system|user)\\s*)*$"
            },
            "description": "Filter by system, user, or both separated by a comma. Other non-empty values return 400."
          },
          {
            "name": "tag_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated `tag_` IDs. Up to 100 IDs."
          },
          {
            "name": "sync_status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["synced", "pending", "failed"]
            },
            "description": "Latest sync state with the general ledger. `pending` does not include `failed`."
          },
          {
            "name": "sync_error_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter failed syncs by error type. Sets `sync_status=failed`; `synced` or `pending` return HTTP 400. Repeat the parameter."
          },
          {
            "name": "sync_attempt_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Latest sync attempt IDs (`jesa_…`), up to 100. An older attempt ID returns no journals."
          },
          {
            "name": "source_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated journal source types to include. You cannot send it with `exclude_source_types`."
          },
          {
            "name": "journal_sequence_numbers",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Exact journal sequence numbers, such as JE-2096, or their numeric part."
          },
          {
            "name": "transaction_sequence_numbers",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated source transaction sequence numbers (such as `OT-1234`). Returns the entries linked to those transactions."
          },
          {
            "name": "exclude_source_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated journal source types to exclude. You cannot send it with `source_types`."
          },
          {
            "name": "updated_since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Return journals updated at or after this time (ISO 8601). Use it to poll for changes."
          },
          {
            "name": "synced_start_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive lower bound on last_synced_at. Includes entries later removed from the external GL."
          },
          {
            "name": "synced_end_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive upper bound on `last_synced_at`. Must be on or after synced_start_date."
          },
          {
            "name": "sync_history_ids",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^sh_[0-9a-fA-F]{24}$"
              }
            },
            "description": "Filter by general-ledger sync history IDs (`sh_…`)."
          },
          {
            "name": "created_since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Return entries whose `created_at` is at or after this ISO-8601 timestamp (inclusive)."
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          },
          {
            "name": "journal_entry_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "IDs to return, separated by commas. The other filters also apply."
          },
          {
            "name": "ledger_account_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Match entries with a line in any of these ledger accounts. The response includes all lines; use matching lines when totaling an account."
          },
          {
            "name": "accounting_period_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Any of these accounting period IDs."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "transaction_ids",
            "in": "query",
            "required": false,
            "description": "Any of these transaction IDs. No date cutoff applies unless you set a date filter.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Transaction ID (`txn_…`).",
                "example": "txn_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "template_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more template ids. Repeat the parameter or send a comma-separated list. Up to 100 IDs."
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/JournalEntry"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "je_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "sequence_number": "JE-42",
                      "status": "draft",
                      "originated_by": "user",
                      "accounting_date": "2026-08-31T12:00:00Z",
                      "posted_at": null,
                      "memo": "Record August opening balance",
                      "source_type": "MANUAL",
                      "sync_date": null,
                      "last_synced_at": null,
                      "last_unsynced_at": null,
                      "legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "transaction_id": null,
                      "transaction_sequence_number": null,
                      "accounting_period_id": null,
                      "classification": null,
                      "tag_ids": [],
                      "reversal_chain": {
                        "previous_entry_id": null,
                        "next_entry_id": null
                      },
                      "period_auto_reassigned": false,
                      "intended_accounting_date": null,
                      "legal_entity_auto_assigned": false,
                      "lines": [
                        {
                          "id": "jel_507f1f77bcf86cd799439011",
                          "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                          "legal_entity_id": "le_507f1f77bcf86cd799439011",
                          "credit_or_debit": "DEBIT",
                          "amount": "100.00",
                          "currency": "USD",
                          "memo": null,
                          "tag_ids": []
                        },
                        {
                          "id": "jel_507f1f77bcf86cd799439012",
                          "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                          "legal_entity_id": "le_507f1f77bcf86cd799439011",
                          "credit_or_debit": "CREDIT",
                          "amount": "100.00",
                          "currency": "USD",
                          "memo": null,
                          "tag_ids": []
                        }
                      ],
                      "is_sync": false,
                      "latest_gl_sync_attempt": null,
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_journal",
        "summary": "Create journal",
        "description": "Creates a journal from a transaction and its ledger account, or from balanced lines. Transaction-based creation resolves the amounts and offsetting account. It creates a draft unless auto_post=true. Closed-period and posting checks still apply.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/JournalEntry"
                    },
                    "read_back_failed": {
                      "type": "boolean",
                      "description": "Present and `true` only when the entry was saved but could not be read back. `data` then contains only `id`; use List journals to read the entry."
                    },
                    "warning": {
                      "type": "string",
                      "description": "Present only when `read_back_failed` is `true`."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "je_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "sequence_number": "JE-42",
                    "status": "draft",
                    "originated_by": "user",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "posted_at": null,
                    "memo": "Customer payment",
                    "sync_date": null,
                    "last_synced_at": null,
                    "last_unsynced_at": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "transaction_id": "txn_507f1f77bcf86cd799439011",
                    "transaction_sequence_number": "OT-42",
                    "accounting_period_id": null,
                    "classification": "DEPOSIT",
                    "tag_ids": [],
                    "reversal_chain": {
                      "previous_entry_id": null,
                      "next_entry_id": null
                    },
                    "period_auto_reassigned": false,
                    "intended_accounting_date": null,
                    "legal_entity_auto_assigned": false,
                    "lines": [
                      {
                        "id": "jel_507f1f77bcf86cd799439011",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "DEBIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      },
                      {
                        "id": "jel_507f1f77bcf86cd799439012",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "CREDIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      }
                    ],
                    "is_sync": false,
                    "latest_gl_sync_attempt": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": ["transaction_id", "ledger_account_id"],
                    "description": "Send exactly one of `transaction_type` or `classification` (its older name).",
                    "oneOf": [
                      {
                        "required": ["transaction_type"],
                        "not": {
                          "required": ["classification"]
                        }
                      },
                      {
                        "required": ["classification"],
                        "not": {
                          "required": ["transaction_type"]
                        }
                      }
                    ],
                    "properties": {
                      "transaction_id": {
                        "type": "string",
                        "description": "The transaction to record. Entendre uses its fiat value, direction, source type and asset type to build the journal lines."
                      },
                      "transaction_type": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/TransactionCategory"
                          }
                        ],
                        "description": "Economic transaction type (for example `WITHDRAWAL`). This is not the accounting classification; `ledger_account_id` selects that treatment."
                      },
                      "classification": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/TransactionCategory"
                          }
                        ],
                        "deprecated": true,
                        "description": "Older name for `transaction_type`. Send only one type field."
                      },
                      "ledger_account_id": {
                        "type": "string",
                        "description": "Postable ledger account for the entry. Entendre selects the offsetting account."
                      },
                      "accounting_date": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 date override. Defaults to transaction date."
                      },
                      "memo": {
                        "type": "string",
                        "description": "Memo."
                      },
                      "tag_ids": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Tag IDs for reporting segmentation."
                      },
                      "auto_post": {
                        "type": "boolean",
                        "description": "Set to `true` to post the journal in the same request. Defaults to `false`, which saves a draft."
                      },
                      "payment_account_id": {
                        "type": "string",
                        "description": "Offsetting ledger account (`lac_…`). Defaults to the ledger account of the transaction source."
                      },
                      "vendor_name": {
                        "type": "string",
                        "description": "Vendor name. Entendre finds or creates a Supplier tag for it and attaches the tag to the entry."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": ["lines"],
                    "properties": {
                      "lines": {
                        "type": "array",
                        "minItems": 2,
                        "maxItems": 500,
                        "description": "Explicit journal entry lines. Total debits must equal total credits exactly.",
                        "items": {
                          "type": "object",
                          "required": ["ledger_account_id", "amount", "credit_or_debit"],
                          "properties": {
                            "ledger_account_id": {
                              "type": "string",
                              "description": "Postable (leaf, non-archived) ledger account (`lac_` prefix)."
                            },
                            "amount": {
                              "oneOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "number"
                                }
                              ],
                              "description": "Positive line amount. Decimal string (`\"125.50\"`) recommended for exactness; JSON numbers are accepted but subject to float representation."
                            },
                            "credit_or_debit": {
                              "type": "string",
                              "enum": ["debit", "credit"],
                              "description": "Line direction. Case-insensitive."
                            },
                            "memo": {
                              "type": "string",
                              "description": "Line memo. A memo of 10 characters or more meets the memo requirement for the line."
                            },
                            "tag_ids": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Tag IDs for this line (`tag_` prefix). Max one tag per key type per line."
                            }
                          }
                        }
                      },
                      "status": {
                        "type": "string",
                        "enum": ["draft", "posted"],
                        "default": "draft",
                        "description": "`posted` creates and posts in one call (same side effects as posting a draft: balances, assets, GL sync)."
                      },
                      "transaction_id": {
                        "type": "string",
                        "description": "Optional transaction link (`txn_` prefix). The transaction must not already have accounting (409 otherwise). Supplies default `accounting_date` and legal entity."
                      },
                      "legal_entity_id": {
                        "type": "string",
                        "description": "Legal entity for the entry (`le_` prefix). Required when the organization has more than one active legal entity and no `transaction_id` is linked."
                      },
                      "accounting_date": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 accounting date. Required when no `transaction_id` is linked; otherwise defaults to the transaction date. Must fall in an open accounting period."
                      },
                      "memo": {
                        "type": "string",
                        "description": "Entry memo. A memo of 10 characters or more meets the memo requirement for all lines."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Transaction": {
                  "summary": "From a transaction",
                  "value": {
                    "transaction_id": "txn_507f1f77bcf86cd799439011",
                    "transaction_type": "DEPOSIT",
                    "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                    "auto_post": false
                  }
                },
                "Journal lines": {
                  "summary": "From journal lines",
                  "value": {
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "currency": "USD",
                    "memo": "September software expense",
                    "lines": [
                      {
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "amount": "100.00",
                        "credit_or_debit": "debit",
                        "memo": "September software expense",
                        "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                      },
                      {
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "amount": "100.00",
                        "credit_or_debit": "credit",
                        "memo": "September software expense",
                        "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/journal-entries/{journal_id}": {
      "patch": {
        "operationId": "update_journal",
        "summary": "Update journal",
        "description": "Update the memo, accounting date or tags of a draft journal. Omitted fields stay unchanged. Use Post journal to post an entry. This operation does not accept status changes or replacement lines.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "journal_id",
            "in": "path",
            "required": true,
            "description": "ID of the journal.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "je_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional key for this request. Retry with the same key and body after a timeout. Keys are kept for at least 24 hours. Reusing a key with a different request returns HTTP 409.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/JournalEntry"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "examples": {
                  "Edited draft": {
                    "value": {
                      "data": {
                        "id": "je_507f1f77bcf86cd799439011",
                        "organization_id": "org_507f1f77bcf86cd799439011",
                        "sequence_number": "JE-42",
                        "status": "draft",
                        "originated_by": "user",
                        "accounting_date": "2026-08-31T12:00:00Z",
                        "posted_at": null,
                        "memo": "Record August opening balance",
                        "source_type": "MANUAL",
                        "sync_date": null,
                        "last_synced_at": null,
                        "last_unsynced_at": null,
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "transaction_id": null,
                        "transaction_sequence_number": null,
                        "accounting_period_id": null,
                        "classification": null,
                        "tag_ids": [],
                        "reversal_chain": {
                          "previous_entry_id": null,
                          "next_entry_id": null
                        },
                        "period_auto_reassigned": false,
                        "intended_accounting_date": null,
                        "legal_entity_auto_assigned": false,
                        "lines": [
                          {
                            "id": "jel_507f1f77bcf86cd799439011",
                            "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                            "legal_entity_id": "le_507f1f77bcf86cd799439011",
                            "credit_or_debit": "DEBIT",
                            "amount": "100.00",
                            "currency": "USD",
                            "memo": null,
                            "tag_ids": []
                          },
                          {
                            "id": "jel_507f1f77bcf86cd799439012",
                            "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                            "legal_entity_id": "le_507f1f77bcf86cd799439011",
                            "credit_or_debit": "CREDIT",
                            "amount": "100.00",
                            "currency": "USD",
                            "memo": null,
                            "tag_ids": []
                          }
                        ],
                        "is_sync": false,
                        "latest_gl_sync_attempt": null,
                        "created_at": "2026-08-31T12:00:00Z",
                        "updated_at": "2026-08-31T12:00:00Z"
                      }
                    }
                  },
                  "Posted journal": {
                    "value": {
                      "data": {
                        "id": "je_507f1f77bcf86cd799439011",
                        "organization_id": "org_507f1f77bcf86cd799439011",
                        "sequence_number": "JE-42",
                        "status": "posted",
                        "originated_by": "user",
                        "accounting_date": "2026-08-31T12:00:00Z",
                        "posted_at": "2026-09-15T18:00:00Z",
                        "memo": "Record August opening balance",
                        "source_type": "MANUAL",
                        "sync_date": null,
                        "last_synced_at": null,
                        "last_unsynced_at": null,
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "transaction_id": null,
                        "transaction_sequence_number": null,
                        "accounting_period_id": "ap_507f1f77bcf86cd799439011",
                        "classification": null,
                        "tag_ids": [],
                        "reversal_chain": {
                          "previous_entry_id": null,
                          "next_entry_id": null
                        },
                        "period_auto_reassigned": false,
                        "intended_accounting_date": null,
                        "legal_entity_auto_assigned": false,
                        "lines": [
                          {
                            "id": "jel_507f1f77bcf86cd799439011",
                            "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                            "legal_entity_id": "le_507f1f77bcf86cd799439011",
                            "credit_or_debit": "DEBIT",
                            "amount": "100.00",
                            "currency": "USD",
                            "memo": null,
                            "tag_ids": []
                          },
                          {
                            "id": "jel_507f1f77bcf86cd799439012",
                            "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                            "legal_entity_id": "le_507f1f77bcf86cd799439011",
                            "credit_or_debit": "CREDIT",
                            "amount": "100.00",
                            "currency": "USD",
                            "memo": null,
                            "tag_ids": []
                          }
                        ],
                        "is_sync": false,
                        "latest_gl_sync_attempt": null,
                        "created_at": "2026-08-31T12:00:00Z",
                        "updated_at": "2026-09-15T18:00:00Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "memo": {
                    "type": "string",
                    "description": "Memo."
                  },
                  "accounting_date": {
                    "type": "string",
                    "format": "date-time",
                    "description": "New accounting date. A date in a closed period moves to the current open period and sets `period_auto_reassigned`. A soft-closed date returns HTTP 400."
                  },
                  "tag_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tag IDs (`tag_…`). Send `[]` to clear the tags."
                  }
                }
              },
              "examples": {
                "Edit draft": {
                  "value": {
                    "memo": "September software expense",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "lines": [
                      {
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "amount": "100.00",
                        "credit_or_debit": "debit",
                        "memo": "September software expense",
                        "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                      },
                      {
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "amount": "100.00",
                        "credit_or_debit": "credit",
                        "memo": "September software expense",
                        "tag_ids": ["tag_507f1f77bcf86cd799439011"]
                      }
                    ]
                  }
                },
                "Post journal": {
                  "value": {
                    "status": "posted"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_journal",
        "summary": "Delete journal",
        "description": "Deletes a draft, error or unposted journal. Synced journals must be unsynced first; posted journals cannot be deleted.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "journal_id",
            "in": "path",
            "required": true,
            "description": "ID of the journal.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "je_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/journal-entries/{journal_id}/reverse": {
      "post": {
        "operationId": "reverse_journal",
        "summary": "Reverse journal",
        "description": "Create a linked compensating journal with explicit date and reason; preserve the original.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "journal_id",
            "in": "path",
            "required": true,
            "description": "ID of the journal.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "je_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/JournalEntry"
                    },
                    "read_back_failed": {
                      "type": "boolean",
                      "description": "Present and `true` only when the entry was saved but could not be read back. `data` then contains only `id`; use List journals to read the entry."
                    },
                    "warning": {
                      "type": "string",
                      "description": "Present only when `read_back_failed` is `true`."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "je_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "sequence_number": "JE-42",
                    "status": "draft",
                    "originated_by": "user",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "posted_at": null,
                    "memo": "Record August opening balance",
                    "source_type": "MANUAL",
                    "sync_date": null,
                    "last_synced_at": null,
                    "last_unsynced_at": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "transaction_id": null,
                    "transaction_sequence_number": null,
                    "accounting_period_id": null,
                    "classification": null,
                    "tag_ids": [],
                    "reversal_chain": {
                      "previous_entry_id": null,
                      "next_entry_id": null
                    },
                    "period_auto_reassigned": false,
                    "intended_accounting_date": null,
                    "legal_entity_auto_assigned": false,
                    "lines": [
                      {
                        "id": "jel_507f1f77bcf86cd799439011",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "DEBIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      },
                      {
                        "id": "jel_507f1f77bcf86cd799439012",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "CREDIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      }
                    ],
                    "is_sync": false,
                    "latest_gl_sync_attempt": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/vault/documents": {
      "get": {
        "operationId": "list_documents",
        "summary": "List documents",
        "description": "Returns document metadata, extraction results, processing errors and permitted download URLs. Filter by document IDs or the available search fields.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "document_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated `doc_<uuid>` ids to filter by. Up to 100 IDs."
          },
          {
            "name": "created_from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Earliest created date (YYYY-MM-DD)."
          },
          {
            "name": "created_to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Latest created date (YYYY-MM-DD)."
          },
          {
            "name": "search_term",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Full-text match across extracted text, summary, filename, vendor name, and bill/receipt numbers."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by document type.",
            "schema": {
              "type": "string",
              "enum": ["bill", "receipt", "statement", "other"]
            }
          },
          {
            "name": "source_id",
            "in": "query",
            "required": false,
            "description": "Source ID (`src_…`).",
            "schema": {
              "type": "string",
              "example": "src_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "vendor_id",
            "in": "query",
            "required": false,
            "description": "Vendor ID (`vnd_…`).",
            "schema": {
              "type": "string",
              "example": "vnd_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated expansions: `bill`, `receipt`, `vendor`, `statement`, `statement.lines` or `download`. `statement.lines` and `download` require exactly one `document_ids` value. `download` requires a user-scoped API key."
          },
          {
            "name": "statement_limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            },
            "description": "Rows per statement page. Requires expand=statement.lines and exactly one document_ids value. Does not change the document page size."
          },
          {
            "name": "statement_cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The `statement.lines.next_cursor` value from the previous page."
          },
          {
            "name": "vendor_name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Vendor name (substring match)."
          },
          {
            "name": "bill_number",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Bill number."
          },
          {
            "name": "bill_date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Earliest bill date (YYYY-MM-DD)."
          },
          {
            "name": "bill_date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Latest bill date (YYYY-MM-DD)."
          },
          {
            "name": "billing_period_start_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Earliest billing-period start (YYYY-MM-DD)."
          },
          {
            "name": "billing_period_end_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Latest billing-period end (YYYY-MM-DD)."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Currency code (such as USD)."
          },
          {
            "name": "total_amount_min",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum total amount, inclusive."
          },
          {
            "name": "total_amount_max",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Maximum total amount, inclusive."
          },
          {
            "name": "tax_amount_min",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum tax amount, inclusive."
          },
          {
            "name": "tax_amount_max",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Maximum tax amount, inclusive."
          },
          {
            "name": "tax_rate_min",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Minimum tax rate, inclusive."
          },
          {
            "name": "tax_rate_max",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            },
            "description": "Maximum tax rate, inclusive."
          },
          {
            "name": "import_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["pending", "imported", "ignored", "duplicate", "invalid"]
            },
            "description": "Nested statement-line filter. Requires expand=statement.lines."
          },
          {
            "name": "vendor_ids",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "maxItems": 100
            },
            "description": "Bill filter. Comma-separated `vnd_` ids; a bill matches any of them. Combines with `vendor_id`. Requires `type=bill` or an omitted type."
          },
          {
            "name": "reconciliation_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["reconciled", "not_reconciled"]
            },
            "description": "Statement filter on `statement.reconciliation_status`. Requires `type=statement`."
          },
          {
            "name": "is_reconciled",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Nested statement-line filter on `is_reconciled`. Requires `expand=statement.lines`."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded. With `expand`, each row is an envelope: `document` holds the document, next to the requested `bill`, `receipt`, `vendor` or `statement`.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/VaultDocument"
                          },
                          {
                            "$ref": "#/components/schemas/VaultDocumentEnvelope"
                          }
                        ]
                      },
                      "description": "The documents. Each item is a document, or an envelope when you send `expand`."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "examples": {
                  "Documents": {
                    "value": {
                      "data": [
                        {
                          "id": "doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601",
                          "organization_id": "org_123",
                          "document_type": "statement",
                          "document_source": "upload",
                          "file_size": 1,
                          "filename": "august-statement.pdf",
                          "original_filename": null,
                          "file_extension": "pdf",
                          "summary": null,
                          "confidence_level": 1,
                          "language": null,
                          "created_at": null,
                          "deleted_at": null,
                          "download_url": "https://files.example.com/documents/statement.pdf"
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  },
                  "Statement rows": {
                    "value": {
                      "data": [
                        {
                          "id": "doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601",
                          "organization_id": "org_123",
                          "document_type": "statement",
                          "document_source": "upload",
                          "file_size": 1,
                          "filename": "august-statement.pdf",
                          "original_filename": null,
                          "file_extension": "pdf",
                          "summary": null,
                          "confidence_level": 1,
                          "language": null,
                          "created_at": null,
                          "deleted_at": null,
                          "download_url": "https://files.example.com/documents/statement.pdf"
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "upload_document",
        "summary": "Upload document",
        "description": "Uploads a base64-encoded file. Requires write:vault and a user-associated API key. Returns the document ID and extracted summary. Creating a bill can also post a journal entry.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional retry key. Check X-Idempotency-Applied before relying on replay protection.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Uploaded document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "properties": {
                    "data": {
                      "type": "object",
                      "required": ["document_id", "filename", "document_type", "summary", "message"],
                      "properties": {
                        "document_id": {
                          "type": ["string", "null"],
                          "description": "Document ID (`doc_…`)."
                        },
                        "filename": {
                          "type": ["string", "null"],
                          "description": "File name."
                        },
                        "document_type": {
                          "type": ["string", "null"],
                          "description": "Document type."
                        },
                        "summary": {
                          "type": ["string", "null"],
                          "description": "Summary of the document."
                        },
                        "message": {
                          "type": "string",
                          "description": "Summary message."
                        },
                        "document": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The document."
                        }
                      },
                      "description": "The uploaded document."
                    }
                  }
                },
                "example": {
                  "data": {
                    "document_id": "doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601",
                    "filename": "invoice.pdf",
                    "document_type": "bill",
                    "summary": "Vendor invoice.",
                    "message": "File uploaded"
                  }
                }
              }
            },
            "headers": {
              "Location": {
                "description": "URL to retrieve the created document.",
                "schema": {
                  "type": "string"
                },
                "example": "/v1/vault/documents/doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601"
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["filename", "base64"],
                "properties": {
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "File name, including the extension."
                  },
                  "base64": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Base64-encoded file contents. The base64 string is capped at 14 MB (~10.5 MB decoded).",
                    "maxLength": 14680064
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "filename": "note.txt",
                "base64": "SGVsbG8="
              }
            }
          }
        }
      }
    },
    "/v1/vault/documents/{document_id}": {
      "patch": {
        "operationId": "update_document",
        "summary": "Update document",
        "description": "Rename a document or move it to another folder.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "description": "ID of the document.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "doc_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/VaultDocument"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601",
                    "organization_id": "org_123",
                    "document_type": "statement",
                    "document_source": "upload",
                    "file_size": 1,
                    "filename": "august-statement.pdf",
                    "original_filename": null,
                    "file_extension": "pdf",
                    "summary": null,
                    "confidence_level": 1,
                    "language": null,
                    "created_at": null,
                    "deleted_at": null,
                    "download_url": "https://files.example.com/documents/statement.pdf"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 512,
                    "description": "File name, including the extension."
                  },
                  "file_directory": {
                    "type": "string",
                    "maxLength": 1024,
                    "description": "Folder to move the document to."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_document",
        "summary": "Delete document",
        "description": "Soft-deletes a document. Requires write:vault. Related accounting records and the stored file remain. Unknown, inaccessible, or already deleted documents return 404.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "description": "ID of the document.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "doc_6f31e8c4-41ce-47af-9db7-3ad295a0a601"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/legal-entities": {
      "get": {
        "operationId": "list_legal_entities",
        "summary": "List legal entities",
        "description": "Lists legal entities and their reporting defaults. Filter by `legal_entity_ids` to retrieve one or more records. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.\n\nSet `include_archived=true` to include archived records, including when filtering by ID.",
        "tags": ["Legal Entities"],
        "parameters": [
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["le_456def"]
          },
          {
            "name": "include_archived",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Include archived legal entities. Defaults to false. An explicit status filter takes precedence."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["name", "created_at", "updated_at"]
            },
            "description": "Field to sort by. Defaults to `created_at`. Use `created_at` or `name` to page through all records. With `updated_at`, a record that changes during paging can be skipped."
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            },
            "description": "Sort direction. Defaults to `desc` (newest first)."
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive substring match on the legal entity name."
          },
          {
            "name": "include_count",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails."
          },
          {
            "name": "legal_entity_types",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter to one or more entity types. Repeat the parameter for each value."
          },
          {
            "name": "currencies",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter to one or more base currencies (ISO 4217). Repeat the parameter for each value."
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["active", "archived"]
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by active or archived status. Repeat the parameter for multiple values, or use a comma-separated list. Values are case-insensitive."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["active", "archived"]
            },
            "description": "Filter by status."
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LegalEntity"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "le_456def",
                      "name": "Example Company",
                      "entity_type": "C-CORP",
                      "status": "active",
                      "base_currency": "USD",
                      "address": {
                        "line1": "100 Example Street",
                        "line2": null,
                        "city": "New York",
                        "state": null,
                        "country": "US",
                        "zipcode": "10001"
                      },
                      "address_string": null,
                      "created_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_legal_entity",
        "summary": "Create legal entity",
        "description": "Create a legal entity with its jurisdiction and reporting currency.",
        "tags": ["Legal Entities"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/LegalEntity"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "le_456def",
                    "name": "Example Company",
                    "entity_type": "C-CORP",
                    "status": "active",
                    "base_currency": "USD",
                    "address": {
                      "line1": "100 Example Street",
                      "line2": null,
                      "city": "New York",
                      "state": null,
                      "country": "US",
                      "zipcode": "10001"
                    },
                    "address_string": null,
                    "created_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "entity_type", "base_currency"],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Display name for the legal entity."
                  },
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "C-CORP",
                      "S-CORP",
                      "LLC",
                      "LP",
                      "LLP",
                      "GmbH",
                      "Ltd",
                      "PLC",
                      "Foundation",
                      "Trust",
                      "Non-Profit",
                      "Sole Proprietorship",
                      "DAO",
                      "Other"
                    ],
                    "description": "Legal entity type."
                  },
                  "base_currency": {
                    "type": "string",
                    "description": "Base reporting currency (ISO 4217).",
                    "examples": ["USD", "EUR"]
                  },
                  "address": {
                    "$ref": "#/components/schemas/Address"
                  },
                  "address_string": {
                    "type": ["string", "null"],
                    "maxLength": 500,
                    "description": "Address as one line of text, up to 500 characters. When you also send `address`, `address` takes precedence."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Example Company",
                "entity_type": "C-CORP",
                "base_currency": "USD"
              }
            }
          }
        }
      }
    },
    "/v1/legal-entities/{legal_entity_id}": {
      "patch": {
        "operationId": "update_legal_entity",
        "summary": "Update legal entity",
        "description": "Update legal entity details or archive the entity. Changes that conflict with its accounting history are rejected.",
        "tags": ["Legal Entities"],
        "parameters": [
          {
            "name": "legal_entity_id",
            "in": "path",
            "required": true,
            "description": "ID of the legal entity.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "le_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/LegalEntity"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "le_456def",
                    "name": "Example Company",
                    "entity_type": "C-CORP",
                    "status": "active",
                    "base_currency": "USD",
                    "address": {
                      "line1": "100 Example Street",
                      "line2": null,
                      "city": "New York",
                      "state": null,
                      "country": "US",
                      "zipcode": "10001"
                    },
                    "address_string": null,
                    "created_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Updated display name."
                  },
                  "status": {
                    "type": "string",
                    "enum": ["active", "archived"],
                    "description": "Updated status."
                  },
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "C-CORP",
                      "S-CORP",
                      "LLC",
                      "LP",
                      "LLP",
                      "GmbH",
                      "Ltd",
                      "PLC",
                      "Foundation",
                      "Trust",
                      "Non-Profit",
                      "Sole Proprietorship",
                      "DAO",
                      "Other"
                    ],
                    "description": "Legal entity type."
                  },
                  "base_currency": {
                    "type": "string",
                    "description": "Base reporting currency (ISO 4217). Applies to new data only; past journals do not change.",
                    "examples": ["USD", "EUR"]
                  },
                  "address": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/Address"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Replace the structured address. Set `null` to clear."
                  },
                  "address_string": {
                    "type": ["string", "null"],
                    "maxLength": 500,
                    "description": "Address as one line of text, up to 500 characters. Send `null` to clear it. `address` takes precedence when both are set."
                  }
                },
                "minProperties": 1,
                "additionalProperties": false
              },
              "example": {
                "name": "Example Company",
                "status": "active",
                "entity_type": "C-CORP",
                "base_currency": "USD",
                "address": {
                  "line1": "100 Example Street",
                  "line2": null,
                  "city": "New York",
                  "state": null,
                  "country": "US",
                  "zipcode": "10001"
                },
                "address_string": null
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_legal_entity",
        "summary": "Delete legal entity",
        "description": "Soft-delete an empty legal entity. Transactions, journal entries or linked wallets prevent deletion. Archive the entity or remove its references first. Provider connections are not disconnected.",
        "tags": ["Legal Entities"],
        "parameters": [
          {
            "name": "legal_entity_id",
            "in": "path",
            "required": true,
            "description": "ID of the legal entity.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "le_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The entity has transactions, journal entries or linked wallets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged"
      }
    },
    "/v1/ledger-accounts": {
      "get": {
        "operationId": "list_ledger_accounts",
        "summary": "List ledger accounts",
        "description": "Lists ledger accounts and their posting settings. Filter by `ledger_account_ids` to retrieve one or more records. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.\n\nSet `include_archived=true` to include archived records, including when filtering by ID.",
        "tags": ["Ledger Accounts"],
        "parameters": [
          {
            "name": "ledger_account_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Comma-separated account types. Allowed: `Asset`, `Liability`, `Equity`, `Income`, `Expense`.",
            "x-deprecated-aliases": ["type"]
          },
          {
            "name": "is_postable",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "`true` for postable child accounts only, `false` for parent grouping accounts only."
          },
          {
            "name": "include_archived",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Include archived ledger accounts. Defaults to false."
          },
          {
            "name": "is_clearing_account",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter to clearing accounts (`true`) or non-clearing accounts (`false`)."
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["sequence", "name"]
            },
            "description": "Field to sort by. Defaults to `sequence` (chart-of-accounts order)."
          },
          {
            "name": "sort_direction",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            },
            "description": "Sort direction."
          },
          {
            "name": "include_count",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails."
          },
          {
            "name": "ledger_account_ids",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter to specific `lac_`-prefixed ledger account IDs. Up to 100 IDs."
          },
          {
            "name": "parent_ledger_account_ids",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter to children of the given `lac_`-prefixed parent account IDs. Up to 100 IDs."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LedgerAccount"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "lac_507f1f77bcf86cd799439011",
                      "name": "Cash",
                      "type": "Asset",
                      "normal_balance": "debit",
                      "sequence_number": 1000,
                      "parent_account_id": null,
                      "is_postable": true,
                      "is_clearing_account": false,
                      "is_archived": false,
                      "archived_at": null,
                      "asset_type": null,
                      "created_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_ledger_account",
        "summary": "Create ledger account",
        "description": "Create a ledger account in your organization’s chart of accounts.",
        "tags": ["Ledger Accounts"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/LedgerAccount"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "lac_507f1f77bcf86cd799439011",
                    "name": "Cash",
                    "type": "Asset",
                    "normal_balance": "debit",
                    "sequence_number": 1000,
                    "parent_account_id": null,
                    "is_postable": true,
                    "is_clearing_account": false,
                    "is_archived": false,
                    "archived_at": null,
                    "asset_type": null,
                    "created_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "type", "legal_entity_id"],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Display name (such as `Mercury Checking`)."
                  },
                  "type": {
                    "type": "string",
                    "enum": ["Asset", "Liability", "Equity", "Income", "Expense"],
                    "description": "Account type."
                  },
                  "sequence_number": {
                    "type": "integer",
                    "description": "Account number in the chart of accounts."
                  },
                  "parent_account_id": {
                    "type": "string",
                    "description": "Prefixed parent account ID. Omit for top-level."
                  },
                  "is_clearing_account": {
                    "type": "boolean",
                    "description": "Marks the account as a clearing or suspense account. Defaults to `false`."
                  },
                  "legal_entity_id": {
                    "type": "string",
                    "description": "Ignored. Ledger accounts belong to the organization, not to a legal entity."
                  },
                  "asset_type": {
                    "type": "string",
                    "description": "Token or currency type (such as `ETH`, `USD`)."
                  }
                }
              },
              "example": {
                "name": "Software expense",
                "type": "Asset"
              }
            }
          }
        }
      }
    },
    "/v1/ledger-accounts/{ledger_account_id}": {
      "patch": {
        "operationId": "update_ledger_account",
        "summary": "Update ledger account",
        "description": "Update the name, account type, sequence, parent, clearing flag or asset type. Parent changes preserve tenant ownership and reject cycles. Account and parent leaf flags are recalculated.",
        "tags": ["Ledger Accounts"],
        "parameters": [
          {
            "name": "ledger_account_id",
            "in": "path",
            "required": true,
            "description": "ID of the ledger account.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "lac_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/LedgerAccount"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "lac_507f1f77bcf86cd799439011",
                    "name": "Cash",
                    "type": "Asset",
                    "normal_balance": "debit",
                    "sequence_number": 1000,
                    "parent_account_id": null,
                    "is_postable": true,
                    "is_clearing_account": false,
                    "is_archived": false,
                    "archived_at": null,
                    "asset_type": null,
                    "created_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New display name."
                  },
                  "sequence_number": {
                    "type": "integer",
                    "description": "New chart-of-accounts sequence number."
                  },
                  "parent_account_id": {
                    "type": ["string", "null"],
                    "description": "Parent account ID (`lac_…`), or `null` to move the account to the top level. Entendre prevents cycles and checks the depth."
                  },
                  "is_clearing_account": {
                    "type": "boolean",
                    "description": "Marks the account as a clearing or suspense account."
                  },
                  "asset_type": {
                    "type": "string",
                    "description": "Token or currency symbol the account tracks (such as `ETH`, `USD`)."
                  },
                  "type": {
                    "type": "string",
                    "enum": ["asset", "liability", "equity", "income", "expense"],
                    "description": "Ledger account type."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_ledger_account",
        "summary": "Delete ledger account",
        "description": "Deletes an unused ledger account and its unused descendants. References anywhere in the subtree block deletion.",
        "tags": ["Ledger Accounts"],
        "parameters": [
          {
            "name": "ledger_account_id",
            "in": "path",
            "required": true,
            "description": "ID of the ledger account.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "lac_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "privileged"
      }
    },
    "/v1/tags": {
      "get": {
        "operationId": "list_tags",
        "summary": "List tags",
        "description": "Lists organization tags. Filter by `tag_ids` to retrieve one or more records. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.",
        "tags": ["Tags"],
        "parameters": [
          {
            "name": "tag_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["tag_456ghi"]
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Field to sort by. Defaults to `created_at`. Use `created_at` to page through all tags. With `updated_at`, a tag that changes during paging can be skipped.",
            "schema": {
              "type": "string",
              "enum": ["created_at", "updated_at"]
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "required": false,
            "description": "Sort direction. Defaults to `desc` (newest first).",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Usable or retained for history.",
            "schema": {
              "type": "string",
              "enum": ["active", "archived"]
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search in labels and descriptions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "description": "Tag key. Must be one of the listed values. Other values return HTTP `400`.",
            "schema": {
              "type": "string",
              "enum": [
                "Customer",
                "Supplier",
                "System",
                "ID",
                "Bank Account",
                "Cost Center",
                "Class",
                "Staff",
                "Product",
                "Workflow",
                "Review Status",
                "Custom"
              ]
            }
          },
          {
            "name": "value",
            "in": "query",
            "required": false,
            "description": "Tag value search.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Tag"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "tag_456ghi",
                      "organization_id": "org_abc123",
                      "key": "Customer",
                      "value": "Acme Corp",
                      "status": "active",
                      "usage_count": 0,
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_tag",
        "summary": "Create tag",
        "description": "Creates an organization tag with a key and value. An existing key and value combination returns a conflict.",
        "tags": ["Tags"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Tag"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "tag_456ghi",
                    "organization_id": "org_abc123",
                    "key": "Customer",
                    "value": "Acme Corp",
                    "status": "active",
                    "usage_count": 0,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["key", "value"],
                "properties": {
                  "key": {
                    "type": "string",
                    "enum": [
                      "Customer",
                      "Supplier",
                      "System",
                      "ID",
                      "Bank Account",
                      "Cost Center",
                      "Class",
                      "Staff",
                      "Product",
                      "Workflow",
                      "Review Status",
                      "Custom"
                    ],
                    "description": "Tag key. Must be one of the listed values. Other values return HTTP `400`."
                  },
                  "value": {
                    "type": "string",
                    "description": "Tag value (the label itself)."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "key": "Customer",
                "value": "Acme Corp"
              }
            }
          }
        }
      }
    },
    "/v1/tags/{tag_id}": {
      "patch": {
        "operationId": "update_tag",
        "summary": "Update tag",
        "description": "Rename a tag, update its metadata or change its archive state.",
        "tags": ["Tags"],
        "parameters": [
          {
            "name": "tag_id",
            "in": "path",
            "required": true,
            "description": "ID of the tag.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "tag_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Tag"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "tag_456ghi",
                    "organization_id": "org_abc123",
                    "key": "Customer",
                    "value": "Acme Corp",
                    "status": "active",
                    "usage_count": 0,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "New tag value."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_tag",
        "summary": "Delete tag",
        "description": "Deletes an unused tag. Tags still linked to records return a conflict.",
        "tags": ["Tags"],
        "parameters": [
          {
            "name": "tag_id",
            "in": "path",
            "required": true,
            "description": "ID of the tag.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "tag_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write"
      }
    },
    "/v1/vault/vendors": {
      "get": {
        "operationId": "list_accrual_vendors",
        "summary": "Find vendors for accruals",
        "description": "Find organization vendors by name and legal entity. Return the IDs, expense account mapping and readiness needed to create accruals. Vendor setup and mapping changes are managed in the dashboard.",
        "tags": ["Accruals"],
        "parameters": [
          {
            "name": "vendor_ids",
            "in": "query",
            "required": false,
            "description": "Vendor IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["vnd_507f1f77bcf86cd799439011"]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Search by vendor name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mapping_status",
            "in": "query",
            "required": false,
            "description": "Required default expense mapping.",
            "schema": {
              "type": "string",
              "enum": ["mapped", "unmapped"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VaultVendor"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "vnd_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "name": "Example Software",
                      "website_url": null,
                      "is_ramp_managed": false,
                      "is_ap_vendor": true,
                      "default_gl_account": null,
                      "payment_terms": null,
                      "external_vendor_id": null,
                      "gl_type": null,
                      "realm_id": null,
                      "default_expense_account_id": null,
                      "last_gl_sync": null,
                      "gl_sync_status": null,
                      "created_at": "2026-08-31T12:00:00Z",
                      "files_count": 2,
                      "total_bills_amount": "1200.00"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/accruals": {
      "get": {
        "operationId": "list_accruals",
        "summary": "List accruals",
        "description": "Lists accruals with existing journals. Defaults to posted; use status=all to include other accrual states.",
        "tags": ["Accruals"],
        "parameters": [
          {
            "name": "journal_sequence_number",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Journal sequence number. Returns the accruals of that journal."
          },
          {
            "name": "accrual_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["acc_507f1f77bcf86cd799439011"]
          },
          {
            "name": "vendor_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter to a single vendor (`vnd_<id>` or a bare id)."
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}$"
            },
            "description": "Accrual period, Month, in `YYYY-MM` format."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["pending", "posted", "reversed", "matched", "all"],
              "default": "posted"
            },
            "description": "Accrual status. Defaults to posted; all removes the status filter."
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "description": "Legal entity ID (`le_…`).",
            "schema": {
              "type": "string",
              "example": "le_507f1f77bcf86cd799439011"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of accruals.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "count"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Accrual"
                      },
                      "description": "The records."
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of accruals on this page."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "acc_507f1f77bcf86cd799439011",
                      "vendor_id": "vnd_507f1f77bcf86cd799439011",
                      "vendor_name": "Example Supplier",
                      "amount": "100.00",
                      "period": "2026-08",
                      "status": "posted",
                      "journal_entry_id": "je_507f1f77bcf86cd799439011",
                      "journal_sequence_number": "JE-42",
                      "created_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_and_post_accruals",
        "summary": "Post accrual entries",
        "description": "Create and post journal entries for one or more vendor accruals. Returns the created entries and any failed items.",
        "tags": ["Accruals"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "Batch processed. Inspect created and failed items; HTTP 200 does not mean every item succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AccrualCreateResult"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "accruals_created": 1,
                    "accruals_failed": 0,
                    "total_amount": "100.00",
                    "reversal_date": "2026-09-01",
                    "created": [
                      {
                        "accrual_id": "acc_507f1f77bcf86cd799439011",
                        "journal_entry_id": "je_507f1f77bcf86cd799439011",
                        "journal_sequence_number": "JE-42",
                        "vendor_id": "vnd_507f1f77bcf86cd799439011",
                        "vendor_name": "Example Supplier",
                        "amount": 100,
                        "period": "2026-08",
                        "reversal_date": "2026-09-01",
                        "confidence": null
                      }
                    ],
                    "failed": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["accruals"],
                "properties": {
                  "accruals": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "required": ["vendor_id", "amount", "period"],
                      "properties": {
                        "vendor_id": {
                          "type": "string",
                          "description": "`vnd_<id>` or bare id."
                        },
                        "vendor_name": {
                          "type": "string",
                          "description": "Vendor name."
                        },
                        "amount": {
                          "type": "number",
                          "description": "Positive accrual amount."
                        },
                        "period": {
                          "type": "string",
                          "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
                          "description": "Month, in `YYYY-MM` format."
                        },
                        "reason": {
                          "type": "string",
                          "description": "Why you accrue the amount."
                        },
                        "confidence": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Your confidence in the amount, from 0 to 100."
                        },
                        "expected_bill_id": {
                          "type": "string",
                          "description": "Bill that you expect to replace the accrual."
                        },
                        "notes": {
                          "type": "string",
                          "description": "Notes."
                        },
                        "legal_entity_id": {
                          "type": "string",
                          "description": "`le_<id>` or bare id."
                        },
                        "legal_entity_name": {
                          "type": "string",
                          "description": "Legal entity name."
                        }
                      }
                    },
                    "maxItems": 100,
                    "description": "Accruals to create."
                  },
                  "auto_reverse": {
                    "type": "boolean",
                    "description": "Reverse the accrual under the reversal policy of the organization. The returned reversal dates come from that policy."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "accruals": [
                  {
                    "vendor_id": "vnd_507f1f77bcf86cd799439011",
                    "vendor_name": "Example Software",
                    "amount": 1,
                    "period": "2026-08",
                    "reason": "Correct the selected accounting records.",
                    "confidence": 1,
                    "expected_bill_id": "ref_507f1f77bcf86cd799439011",
                    "notes": "September subscription",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "legal_entity_name": "Example Company"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/accruals/{accrual_id}/reverse": {
      "post": {
        "operationId": "reverse_accrual",
        "summary": "Reverse accrual",
        "description": "Create a reversal linked to the accrual. Send today’s date (UTC) as the reversal date, and a reason.",
        "tags": ["Accruals"],
        "parameters": [
          {
            "name": "accrual_id",
            "in": "path",
            "required": true,
            "description": "ID of the accrual.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ref_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AccrualReversal"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "accrual_id": "acc_507f1f77bcf86cd799439011",
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "reversal_journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "reversal_date": "2026-08-31",
                    "status": "reversed"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reversal_date": {
                    "type": "string",
                    "description": "Today’s date in UTC (YYYY-MM-DD). Any other date returns HTTP 400: backdated reversals are not supported.",
                    "format": "date"
                  },
                  "reason": {
                    "type": "string",
                    "description": "Reason recorded with the accounting/audit event.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "Correct the selected accounting records."
                  }
                },
                "required": ["reversal_date", "reason"],
                "additionalProperties": false
              },
              "example": {
                "reversal_date": "2026-08-31",
                "reason": "Correct the selected accounting records."
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/invoices": {
      "get": {
        "operationId": "list_eligible_invoices",
        "summary": "List eligible invoices",
        "description": "List Stripe invoices available for cash application, with their eligibility. Legal entity and currency filters are not supported. The response’s `legal_entity_id` is always `null`.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size (1-100). Defaults to 100 when omitted.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "customer_name",
            "in": "query",
            "required": false,
            "description": "Customer name, matched as a substring without case sensitivity. `stripe_customer_id` takes precedence. A name that matches several customers returns an empty page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          {
            "name": "stripe_customer_id",
            "in": "query",
            "required": false,
            "description": "Stripe customer id.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Comma-separated invoice statuses: `open` (the default), `paid`, `draft`, `void` or `uncollectible`. An unknown value matches nothing.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          {
            "name": "amount",
            "in": "query",
            "description": "Match invoices by amount due. Use tolerance to widen the amount range.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tolerance",
            "in": "query",
            "description": "Requires amount. Non-negative range around the requested amount; defaults to 5.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Inclusive lower bound on invoice date. A bare `YYYY-MM-DD` date or a full ISO 8601 timestamp.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Inclusive upper bound on invoice date. A bare `YYYY-MM-DD` date is clamped to end-of-day UTC; a full ISO 8601 timestamp is the exact instant (not clamped).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of invoices eligible for cash application.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data", "has_more", "next_cursor"],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/V1CashApplicationInvoice"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "resolution": {
                      "type": "object",
                      "description": "Customers that match `customer_name`.",
                      "properties": {
                        "customer_name": {
                          "type": ["string", "null"],
                          "description": "Customer name that you sent."
                        },
                        "stripe_customer_id": {
                          "type": ["string", "null"],
                          "description": "Stripe customer ID, when one customer matched."
                        },
                        "message": {
                          "type": ["string", "null"],
                          "description": "Explanation of the match."
                        },
                        "candidates": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Customers that match the name."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "inv_507f1f77bcf86cd799439011",
                      "invoice_number": "1001",
                      "customer_name": "Acme Corp",
                      "customer_id": "cus_acme",
                      "status": "open",
                      "amount_due": "100.00",
                      "total_amount": "100.00",
                      "invoice_date": "2026-08-01T00:00:00.000Z",
                      "due_date": "2026-08-31T00:00:00.000Z",
                      "currency": "USD",
                      "legal_entity_id": null,
                      "transaction_id": null,
                      "provider": "stripe",
                      "eligible": true,
                      "ineligibility_reason": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/cash-applications/preview": {
      "post": {
        "operationId": "preview_cash_application",
        "summary": "Preview cash application",
        "description": "Returns ranked invoice allocations without writing data, reserving the deposit or posting journals. Choose a suggestion and send its allocations when creating a cash application.",
        "tags": ["Cash Application"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CashPreview"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "deposit": {
                      "id": "txn_507f1f77bcf86cd799439011",
                      "amount": "100.00",
                      "memo": "Invoice payment",
                      "txn_date": "2026-08-31T12:00:00Z"
                    },
                    "derived_customer": null,
                    "suggestions": [
                      {
                        "match_type": "exact",
                        "confidence": 1,
                        "total_amount": "100.00",
                        "delta": "0.00",
                        "allocations": [
                          {
                            "target_type": "invoice",
                            "target_id": "inv_507f1f77bcf86cd799439011",
                            "invoice_number": "INV-1001",
                            "amount": "100.00",
                            "customer_name": "Example customer"
                          }
                        ]
                      }
                    ],
                    "candidate_pool_size": 1,
                    "truncated": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["deposit_transaction_id"],
                "properties": {
                  "deposit_transaction_id": {
                    "type": "string",
                    "description": "`txn_…`"
                  },
                  "stripe_customer_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Stripe customer ID. Limits the suggestions to the open invoices of this customer."
                  },
                  "max_suggestions": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20,
                    "description": "Maximum number of suggestions to return."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "deposit_transaction_id": "txn_507f1f77bcf86cd799439011"
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications": {
      "get": {
        "operationId": "list_cash_applications",
        "summary": "List cash applications",
        "description": "Returns allocations, balances and posting state. Filter by application IDs or the available payment fields.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["ca_507f1f77bcf86cd799439011"]
          },
          {
            "name": "stripe_status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["pending", "synced", "failed"]
            },
            "description": "Filter on the Stripe sync sub-state. Takes precedence over `status` = `applied` or `partially_applied`. Combining it with `status` = `draft` or `voided` returns 400."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["draft", "applied", "partially_applied", "voided"]
            },
            "description": "Filter by cash application status."
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "description": "Legal entity ID (`le_…`).",
            "schema": {
              "type": "string",
              "example": "le_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "deposit_transaction_id",
            "in": "query",
            "required": false,
            "description": "Transaction ID (`txn_…`).",
            "schema": {
              "type": "string",
              "example": "txn_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "invoice_id",
            "in": "query",
            "required": false,
            "description": "Invoice ID (`inv_…`).",
            "schema": {
              "type": "string",
              "example": "inv_507f1f77bcf86cd799439011"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/V1CashApplication"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "ca_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                      "status": "applied",
                      "stripe_status": "pending",
                      "match_type": "exact",
                      "total_amount": "100.00",
                      "applied_amount": "100.00",
                      "unapplied_amount": "0.00",
                      "deposit_memo": null,
                      "txn_date": null,
                      "allocations": [
                        {
                          "target_type": "invoice",
                          "target_id": "inv_507f1f77bcf86cd799439011",
                          "invoice_number": "INV-100",
                          "amount": "100.00",
                          "customer_name": "Example Customer"
                        }
                      ],
                      "applied_by": null,
                      "journal_entry_id": "je_507f1f77bcf86cd799439011",
                      "stripe_marked_paid_at": null,
                      "confirmed_by": null,
                      "confirmed_at": null,
                      "created_at": null,
                      "updated_at": null,
                      "error_message": null,
                      "etag": "\"v_example\""
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_and_apply_cash_application",
        "summary": "Create and apply cash application",
        "description": "Creates and applies a cash application, posting its accounting entries. Supply the deposit, invoice allocations and current compiled_rules from organization memory. The server rechecks eligibility and invoice balances; preview results do not reserve funds.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "applied",
                    "stripe_status": "pending",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "100.00",
                    "unapplied_amount": "0.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "stripe_marked_paid_at": null,
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["deposit_transaction_id", "allocations", "compiled_rules"],
                "properties": {
                  "deposit_transaction_id": {
                    "type": "string",
                    "description": "Deposit transaction (`txn_…`)."
                  },
                  "allocations": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "required": ["target_type", "target_id", "amount"],
                      "properties": {
                        "target_type": {
                          "type": "string",
                          "enum": ["invoice"],
                          "description": "Always `invoice`."
                        },
                        "target_id": {
                          "type": "string",
                          "description": "`inv_…`"
                        },
                        "amount": {
                          "type": "string",
                          "description": "Non-negative decimal string. Must equal `invoice.amount_due`; partial allocations are not supported."
                        }
                      }
                    },
                    "maxItems": 100,
                    "description": "Invoice allocations."
                  },
                  "adjustment_ledger_account_id": {
                    "type": "string",
                    "description": "Optional `lac_…` for the adjustment leg. Defaults to the organization's cash-application adjustment account."
                  },
                  "compiled_rules": {
                    "type": "array",
                    "description": "Current routing rules from organization memory. Supply [] only to explicitly use default routing.",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["ruleId", "action", "match"],
                      "properties": {
                        "ruleId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Rule ID."
                        },
                        "action": {
                          "type": "string",
                          "enum": ["route_to_account", "require_human_review"],
                          "description": "What the rule does."
                        },
                        "match": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": ["kind", "operator", "value", "normalizedValue"],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "invoice_line",
                              "description": "What the matcher compares."
                            },
                            "operator": {
                              "type": "string",
                              "enum": ["exact", "contains"],
                              "description": "`exact` or `contains`."
                            },
                            "value": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Text to match."
                            },
                            "normalizedValue": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The text in lowercase, without punctuation."
                            }
                          },
                          "description": "What the rule matches."
                        },
                        "target": {
                          "type": ["object", "null"],
                          "additionalProperties": false,
                          "required": ["accountName"],
                          "properties": {
                            "accountName": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Target ledger account name."
                            },
                            "ledgerAccountId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Target ledger account ID (`lac_…`)."
                            }
                          },
                          "description": "Where the rule routes, or `null`."
                        }
                      }
                    }
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                "allocations": [
                  {
                    "target_type": "invoice",
                    "target_id": "inv_507f1f77bcf86cd799439011",
                    "amount": "100.00"
                  }
                ],
                "compiled_rules": []
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/{application_id}": {
      "patch": {
        "operationId": "update_cash_application",
        "summary": "Update cash application",
        "description": "Edit draft allocations with concurrent-edit protection.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "description": "ID of the application.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ca_507f1f77bcf86cd799439011"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "description": "Required. The `etag` from List cash applications. A missing or stale value returns HTTP 412.",
            "schema": {
              "type": "string"
            },
            "example": "\"v_example\""
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Version tag of the returned resource.",
                "schema": {
                  "type": "string"
                },
                "example": "\"v_example\""
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "applied",
                    "stripe_status": "pending",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "100.00",
                    "unapplied_amount": "0.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "stripe_marked_paid_at": null,
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` is missing, or the resource changed after you read it. Read it again, then decide whether to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PRECONDITION_FAILED",
                    "message": "The resource changed. Read it again before you update it.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["allocations"],
                "properties": {
                  "allocations": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "required": ["target_type", "target_id", "amount"],
                      "properties": {
                        "target_type": {
                          "type": "string",
                          "enum": ["invoice"],
                          "description": "Always `invoice`."
                        },
                        "target_id": {
                          "type": "string",
                          "description": "Invoice ID (`inv_…`)."
                        },
                        "amount": {
                          "type": "string",
                          "description": "Amount to apply (decimal string)."
                        }
                      }
                    },
                    "description": "Invoice allocations."
                  }
                },
                "minProperties": 1,
                "additionalProperties": false
              },
              "example": {
                "allocations": [
                  {
                    "target_type": "invoice",
                    "target_id": "inv_507f1f77bcf86cd799439011",
                    "amount": "100.00"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/{application_id}/apply": {
      "post": {
        "operationId": "apply_cash_application",
        "summary": "Apply cash application",
        "description": "Applies a draft cash application. Supply journal_entry_id to link an eligible posted journal, or compiled_rules to create and post its accounting entries. The server validates the deposit, allocations and journal before applying.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "description": "ID of the application.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ca_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "applied",
                    "stripe_status": "pending",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "100.00",
                    "unapplied_amount": "0.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "stripe_marked_paid_at": null,
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "anyOf": [
                  {
                    "required": ["journal_entry_id"]
                  },
                  {
                    "required": ["compiled_rules"]
                  }
                ],
                "properties": {
                  "journal_entry_id": {
                    "type": "string",
                    "description": "An eligible posted journal entry to link, instead of creating one."
                  },
                  "compiled_rules": {
                    "type": "array",
                    "description": "Routing rules from organization memory. Required without journal_entry_id; an empty array means no overrides.",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["ruleId", "action", "match"],
                      "properties": {
                        "ruleId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Rule ID."
                        },
                        "action": {
                          "type": "string",
                          "enum": ["route_to_account", "require_human_review"],
                          "description": "What the rule does."
                        },
                        "match": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": ["kind", "operator", "value", "normalizedValue"],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "const": "invoice_line",
                              "description": "What the matcher compares."
                            },
                            "operator": {
                              "type": "string",
                              "enum": ["exact", "contains"],
                              "description": "`exact` or `contains`."
                            },
                            "value": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Text to match."
                            },
                            "normalizedValue": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The text in lowercase, without punctuation."
                            }
                          },
                          "description": "What the rule matches."
                        },
                        "target": {
                          "type": ["object", "null"],
                          "additionalProperties": false,
                          "required": ["accountName"],
                          "properties": {
                            "accountName": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Target ledger account name."
                            },
                            "ledgerAccountId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Target ledger account ID (`lac_…`)."
                            }
                          },
                          "description": "Where the rule routes, or `null`."
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "journal_entry_id": "je_507f1f77bcf86cd799439011"
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/{application_id}/unapply": {
      "post": {
        "operationId": "unapply_cash_application",
        "summary": "Unapply cash application",
        "description": "Returns an eligible application to draft. ERP-synced entries require authorization to remove the external posting before the local entry is unposted. Provider-completed applications cannot be unapplied.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "description": "ID of the application.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ca_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "draft",
                    "stripe_status": "pending",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "0.00",
                    "unapplied_amount": "100.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": null,
                    "stripe_marked_paid_at": null,
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Optional. Included in the webhook event."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/{application_id}/complete": {
      "post": {
        "operationId": "complete_cash_application",
        "summary": "Complete cash application",
        "description": "Mark invoices as paid in the connected provider, where supported. The response reports the changes made in that provider.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "description": "ID of the application.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ca_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "applied",
                    "stripe_status": "synced",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "100.00",
                    "unapplied_amount": "0.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "stripe_marked_paid_at": "2026-08-31T12:00:00Z",
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "require_gl_sync": {
                    "type": "boolean",
                    "description": "Set to `true` to require a posted journal that is synced to the general ledger before Stripe marks the invoices paid. Campfire connections always require it."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/cash-applications/{application_id}/void": {
      "post": {
        "operationId": "void_cash_application",
        "summary": "Void cash application",
        "description": "Voids an eligible application and reports any ERP or local unposting failures. Provider-completed applications require recovery in the dashboard.",
        "tags": ["Cash Application"],
        "parameters": [
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "description": "ID of the application.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ca_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/V1CashApplication"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ca_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "deposit_transaction_id": "txn_507f1f77bcf86cd799439011",
                    "status": "voided",
                    "stripe_status": "pending",
                    "match_type": "exact",
                    "total_amount": "100.00",
                    "applied_amount": "100.00",
                    "unapplied_amount": "0.00",
                    "deposit_memo": null,
                    "txn_date": null,
                    "allocations": [
                      {
                        "target_type": "invoice",
                        "target_id": "inv_507f1f77bcf86cd799439011",
                        "invoice_number": "INV-100",
                        "amount": "100.00",
                        "customer_name": "Example Customer"
                      }
                    ],
                    "applied_by": null,
                    "journal_entry_id": "je_507f1f77bcf86cd799439011",
                    "stripe_marked_paid_at": null,
                    "confirmed_by": null,
                    "confirmed_at": null,
                    "created_at": null,
                    "updated_at": null,
                    "error_message": null,
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Optional reason. Stored on the application and included in the webhook event."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/classifications": {
      "post": {
        "operationId": "classify_transactions",
        "summary": "Classify transactions",
        "description": "Classify a batch of transactions and post eligible journal entries. Returns a job ID to check results; items that need review remain unposted.",
        "tags": ["Classification"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted. Check the progress and results with Get classification status, at the `Location` URL.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "description": "URL of the classification job.",
                "schema": {
                  "type": "string"
                },
                "example": "/v1/classifications/cls_507f1f77bcf86cd799439011"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["data"],
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ClassificationJob"
                    }
                  }
                },
                "example": {
                  "data": {
                    "job_id": "cls_507f1f77bcf86cd799439011",
                    "status": "queued",
                    "type": "classification"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "sequence_numbers": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^OT-[0-9]+$"
                    },
                    "maxItems": 100,
                    "description": "OT-#### transaction sequence numbers—the easiest way to target exact transactions."
                  },
                  "transaction_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^txn_"
                    },
                    "maxItems": 100,
                    "description": "Transaction IDs (`txn_…`)."
                  },
                  "date_from": {
                    "type": "string",
                    "format": "date",
                    "description": "Inclusive ISO date. Must be paired with date_to; the range may not exceed 92 days."
                  },
                  "date_to": {
                    "type": "string",
                    "format": "date",
                    "description": "Inclusive ISO date. Must be paired with date_from; the range may not exceed 92 days."
                  },
                  "source_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^fac_"
                    },
                    "maxItems": 100,
                    "description": "Source IDs (`fac_…`). Use `source_types` to filter by platform."
                  },
                  "source_types": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "WALLET",
                        "EXCHANGE_SOURCE",
                        "RAINCARD",
                        "STAKING_SOURCE",
                        "RAIN_BILL_PAY",
                        "NIURAL_SOURCE",
                        "FIREBLOCKS",
                        "BANK_SOURCE",
                        "RAMP_CARD",
                        "RAMP_BANK_ACCOUNT",
                        "RAMP_STATEMENT",
                        "RAMP_REIMBURSEMENT",
                        "MANUAL_BANK_STATEMENT",
                        "MANUAL_EXCHANGE_STATEMENT",
                        "FINCH_PAYROLL",
                        "STRIPE"
                      ]
                    },
                    "maxItems": 30,
                    "description": "Source types, such as WALLET, BANK_SOURCE, RAMP_CARD, RAINCARD, or EXCHANGE_SOURCE."
                  },
                  "legal_entity_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^le_"
                    },
                    "maxItems": 100,
                    "description": "Legal entities (`le_…`)."
                  },
                  "classifications": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "SWAP",
                        "NON_TAXABLE_CONVERSION",
                        "DEPOSIT",
                        "WITHDRAWAL",
                        "BRIDGE",
                        "INTERCOMPANY TRANSFER",
                        "INTERNAL TRANSFER",
                        "FEE",
                        "MINTING",
                        "SPAM",
                        "NFT",
                        "UNKNOWN",
                        "STAKING_REWARD",
                        "VALIDATOR_REWARD",
                        "INVOICE",
                        "BILL",
                        "CLAIM REWARD",
                        "BORROW",
                        "RESERVES CHANGE",
                        "REPAYMENT",
                        "REALIZED_PNL",
                        "INCOME",
                        "EXPENSE",
                        "REFUND",
                        "CHARGEBACK"
                      ]
                    },
                    "maxItems": 30,
                    "description": "Transaction types. Transfer values use spaces: INTERNAL TRANSFER and INTERCOMPANY TRANSFER."
                  },
                  "search_term": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Case-insensitive text search. Must be accompanied by unaccounted_only: false."
                  },
                  "unaccounted_only": {
                    "type": "boolean",
                    "description": "Only transactions without journal entries. Defaults to true outside search mode."
                  },
                  "confidence_threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1,
                    "description": "Minimum confidence for automatic classification. Defaults to 0.85."
                  }
                }
              },
              "example": {
                "transaction_ids": ["txn_507f1f77bcf86cd799439011"]
              }
            }
          }
        }
      }
    },
    "/v1/classifications/{classification_id}": {
      "get": {
        "operationId": "get_classification",
        "summary": "Get classification status",
        "description": "Check classification progress, posting results and transactions that need review. Follow the cursor for more results.",
        "tags": ["Classification"],
        "parameters": [
          {
            "name": "classification_id",
            "in": "path",
            "required": true,
            "description": "ID of the classification.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ref_507f1f77bcf86cd799439011"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Maximum number of result items to return."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor for nested result items, not a different job.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Classification"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "cls_507f1f77bcf86cd799439011",
                    "status": "succeeded",
                    "status_url": "/v1/classifications/cls_507f1f77bcf86cd799439011",
                    "total_count": 3,
                    "processed_count": 3,
                    "totals": {
                      "input": 3,
                      "classified": 3,
                      "pending_review": 0,
                      "unclassified": 0,
                      "auto_posted": 1,
                      "posting_failed": 1,
                      "posting_skipped": 1
                    },
                    "items": [
                      {
                        "transaction_id": "txn_507f1f77bcf86cd799439011",
                        "status": "classified",
                        "classification": "EXPENSE",
                        "category_ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "payment_account_id": "lac_507f1f77bcf86cd799439012",
                        "confidence": 95,
                        "reason": "Matched the transaction to its expense account.",
                        "missing_fields": [],
                        "posting_status": "posted",
                        "journal_entry_id": "je_507f1f77bcf86cd799439011",
                        "posting_message": null
                      },
                      {
                        "transaction_id": "txn_507f1f77bcf86cd799439012",
                        "status": "classified",
                        "classification": "EXPENSE",
                        "category_ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "payment_account_id": "lac_507f1f77bcf86cd799439012",
                        "confidence": 95,
                        "reason": "Matched the transaction to its expense account.",
                        "missing_fields": [],
                        "posting_status": "failed",
                        "journal_entry_id": null,
                        "posting_message": "Posting failed. Review the transaction before retrying."
                      },
                      {
                        "transaction_id": "txn_507f1f77bcf86cd799439013",
                        "status": "classified",
                        "classification": "EXPENSE",
                        "category_ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "payment_account_id": "lac_507f1f77bcf86cd799439012",
                        "confidence": 95,
                        "reason": "Matched the transaction to its expense account.",
                        "missing_fields": [],
                        "posting_status": "skipped",
                        "journal_entry_id": null,
                        "posting_message": "A required posting field is missing."
                      }
                    ],
                    "has_more": false,
                    "next_cursor": null,
                    "error": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "completed_at": "2026-08-31T12:01:00Z",
                    "review_url": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/revaluations": {
      "post": {
        "operationId": "create_revaluation",
        "summary": "Create revaluation",
        "description": "Triggers an asynchronous mark-to-market revaluation job for the accounting period named by `period_id`. The job posts its adjustment journal entries directly — there is no separate preview, review, or apply step. A period with a revaluation already in flight (`started` or `in_progress`) returns its existing row instead of starting a second one.",
        "tags": ["Revaluation"],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "period_id": {
                    "type": "string",
                    "description": "Accounting period ID (`ap_…`)."
                  },
                  "asset_types": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Filter revaluation to specific asset types. Omit for every asset type."
                  },
                  "ledger_account_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Ledger account IDs (`lac_…`), up to 100.",
                    "maxItems": 100
                  },
                  "mark_to_market": {
                    "type": "boolean",
                    "default": false,
                    "description": "Set to `true` to revalue at market prices."
                  }
                },
                "required": ["period_id"],
                "additionalProperties": false
              },
              "example": {
                "period_id": "ap_507f1f77bcf86cd799439011",
                "asset_types": ["ETH", "BTC"],
                "mark_to_market": true
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The revaluation job is queued. If a job for the period is already running, the response returns that job.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Revaluation"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "job_507f1f77bcf86cd799439011",
                    "period_id": "ap_507f1f77bcf86cd799439011",
                    "status": "started",
                    "created_at": "2026-08-31T12:00:00Z",
                    "completed_at": null,
                    "message": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the resource's current state. Refresh and retry with the latest state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The request conflicts with the resource's current state. Refresh and retry with the latest state.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "write"
      },
      "get": {
        "operationId": "list_revaluations",
        "summary": "List revaluations",
        "description": "Lists asset-revaluation job runs, newest first. Filter by `period_id` to see every attempt for one accounting period, or by `status`.",
        "tags": ["Revaluation"],
        "parameters": [
          {
            "name": "period_id",
            "in": "query",
            "required": false,
            "description": "Accounting period ID (`ap_…`). Omit to list all periods.",
            "schema": {
              "type": "string",
              "example": "ap_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Comma-separated statuses to filter to.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["started", "in_progress", "completed", "job_failed", "canceled", "hanged"]
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include `total_count`.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful result.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Revaluation"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "description": "Present only when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "job_507f1f77bcf86cd799439011",
                      "period_id": "ap_507f1f77bcf86cd799439011",
                      "status": "completed",
                      "created_at": "2026-08-31T12:00:00Z",
                      "completed_at": "2026-08-31T12:04:10Z",
                      "message": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/accounting-periods": {
      "get": {
        "operationId": "list_accounting_periods",
        "summary": "List accounting periods",
        "description": "Lists accounting periods, their boundaries and close state. Filter by `accounting_period_ids` to retrieve one or more records. Returns a paginated array, including when filtering by ID. No matches returns HTTP 200 with an empty `data` array.",
        "tags": ["Accounting Periods"],
        "parameters": [
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Exact start date of the period (YYYY-MM-DD), such as `2026-09-01`. Not a lower bound."
          },
          {
            "name": "accounting_period_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["ap_123def"]
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Include the total number of matching records. If the count cannot be calculated, the request fails.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["open", "soft_closed", "closed"]
            },
            "description": "Filter by period status."
          }
        ],
        "responses": {
          "200": {
            "description": "The matching records.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AccountingPeriod"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Total matching records across all pages. Present when include_count=true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "ap_123def",
                      "organization_id": "org_abc123",
                      "name": "September 2026",
                      "start_date": "2026-08-31T12:00:00Z",
                      "end_date": "2026-08-31T12:00:00Z",
                      "status": "open",
                      "legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "closed_on_date": "2026-08-31T12:00:00Z",
                      "closed_by": "usr_507f1f77bcf86cd799439011",
                      "created_at": "2025-01-01T00:00:00.000Z",
                      "updated_at": "2025-01-01T00:00:00.000Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/accounting-periods/{period_id}/close-preflight": {
      "get": {
        "operationId": "check_period_readiness",
        "summary": "Check period readiness",
        "description": "Checks close blockers and returns pending transaction totals and draft journal previews. Resolve outstanding work before closing.",
        "tags": ["Accounting Periods"],
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "description": "ID of the period.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ap_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CloseReadiness"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "accounting_period": {
                      "id": "ap_507f1f77bcf86cd799439011",
                      "status": "Open",
                      "start_date": "2026-08-01",
                      "end_date": "2026-08-31",
                      "legal_entity_id": "le_507f1f77bcf86cd799439011"
                    },
                    "preconditions": {
                      "can_close": false,
                      "blocking_reasons": [
                        "No next accounting period exists. Close requires a successor period to carry closing balances forward."
                      ]
                    },
                    "pending_transactions": {
                      "count": 0,
                      "sum_credit_usd": 0,
                      "sum_debit_usd": 0,
                      "preview": []
                    },
                    "draft_journal_entries": {
                      "count": 1,
                      "preview": [
                        {
                          "sequence_number": "JE-1001",
                          "id": "je_507f1f77bcf86cd799439011",
                          "date": "2026-08-31",
                          "amount_usd": null,
                          "label": "September software expense"
                        }
                      ]
                    },
                    "recommendation": "hold"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "read"
      }
    },
    "/v1/accounting-periods/{period_id}/close": {
      "post": {
        "operationId": "close_accounting_period",
        "summary": "Close accounting period",
        "description": "Close an accounting period. The server checks permissions and close requirements again before closing it.",
        "tags": ["Accounting Periods"],
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "description": "ID of the period.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ap_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AccountingPeriod"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ap_123def",
                    "organization_id": "org_abc123",
                    "name": "September 2026",
                    "start_date": "2026-08-31T12:00:00Z",
                    "end_date": "2026-08-31T12:00:00Z",
                    "status": "closed",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "closed_on_date": "2026-08-31T12:00:00Z",
                    "closed_by": "usr_507f1f77bcf86cd799439011",
                    "created_at": "2025-01-01T00:00:00.000Z",
                    "updated_at": "2025-01-01T00:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "privileged"
      }
    },
    "/v1/accounting-periods/{period_id}/reopen": {
      "post": {
        "operationId": "reopen_accounting_period",
        "summary": "Reopen accounting period",
        "description": "Reopen an accounting period. Provide a reason. The server checks permissions and records who made the change.",
        "tags": ["Accounting Periods"],
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "description": "ID of the period.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "ap_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AccountingPeriod"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "ap_123def",
                    "organization_id": "org_abc123",
                    "name": "September 2026",
                    "start_date": "2026-08-31T12:00:00Z",
                    "end_date": "2026-08-31T12:00:00Z",
                    "status": "open",
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "closed_on_date": "2026-08-31T12:00:00Z",
                    "closed_by": "usr_507f1f77bcf86cd799439011",
                    "created_at": "2025-01-01T00:00:00.000Z",
                    "updated_at": "2025-01-01T00:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Accounting",
        "x-access-class": "privileged"
      }
    },
    "/v1/reports/income-statement": {
      "get": {
        "operationId": "get_income_statement",
        "summary": "Get income statement",
        "description": "Returns revenue, expenses and profit. Filter by accounting period IDs or by a start_date/end_date pair; do not combine them. Omit both to return every accounting period as a column.",
        "tags": ["Income Statement"],
        "parameters": [
          {
            "name": "tag_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prefixed tag ID (`tag_`). Filters the report to one tag. Get tag IDs from List tags."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Start of the window (ISO 8601, inclusive). Send with `end_date`. A date inside a period returns the full period. You cannot send it with `accounting_period_id` or `accounting_period_ids`."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive end of the window (ISO 8601). Send it with `start_date`. Each column is a whole accounting period, so a date inside a period returns the full period."
          },
          {
            "name": "include_zero_rows",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Set to `false` to omit accounts that are zero in every period. Defaults to `true`."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "accounting_period_id",
            "in": "query",
            "required": false,
            "description": "Accounting period ID (`ap_…`).",
            "schema": {
              "type": "string",
              "example": "ap_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "accounting_period_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Accounting period IDs (`ap_…`), up to 100. Omit to return every period.",
            "style": "form",
            "explode": true
          },
          {
            "name": "verbosity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["faithful", "compact"],
              "default": "faithful"
            },
            "description": "`faithful` (the default) returns all fields. `compact` returns the same figures in a smaller shape."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/IncomeStatement"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "ledger_accounts": [
                      {
                        "id": "lac_507f1f77bcf86cd799439011",
                        "name": "Cash",
                        "type": "Asset",
                        "normal_balance": "debit",
                        "sequence_number": 1000,
                        "parent_account_id": null,
                        "is_postable": true,
                        "is_clearing_account": false,
                        "is_archived": false,
                        "archived_at": null,
                        "asset_type": null,
                        "created_at": "2026-08-31T12:00:00Z"
                      }
                    ],
                    "balances": {
                      "lac_507f1f77bcf86cd799439011": {
                        "2026-08": {
                          "credit_debit": {
                            "opening_balance": {
                              "value": "0.00"
                            },
                            "closing_balance": {
                              "value": "0.00"
                            },
                            "current_balance": {
                              "value": "0.00"
                            },
                            "debits": {
                              "value": "0.00"
                            },
                            "credits": {
                              "value": "0.00"
                            },
                            "accounting_period_start_date_utc": null,
                            "legal_entity_ids": ["le_507f1f77bcf86cd799439011"]
                          },
                          "tag_balance": {
                            "value": "0.00"
                          }
                        }
                      }
                    },
                    "data_quality": {
                      "warnings": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/balance-sheet": {
      "get": {
        "operationId": "get_balance_sheet",
        "summary": "Get balance sheet",
        "description": "Returns assets, liabilities and equity by accounting period. Filter by accounting period IDs or by a start_date/end_date pair; do not combine them. Omit both to return every accounting period as a column.",
        "tags": ["Balance Sheet"],
        "parameters": [
          {
            "name": "tag_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prefixed tag ID (`tag_`). Filters the report to one tag. Get tag IDs from List tags."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Start of the window (ISO 8601, inclusive). Send with `end_date`. A date inside a period returns the full period. You cannot send it with `accounting_period_id` or `accounting_period_ids`."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Inclusive end of the window (ISO 8601). Send it with `start_date`. Each column is a whole accounting period, so a date inside a period returns the full period."
          },
          {
            "name": "include_zero_rows",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Set to `false` to omit accounts that are zero in every period. Defaults to `true`."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "accounting_period_id",
            "in": "query",
            "required": false,
            "description": "Accounting period ID (`ap_…`).",
            "schema": {
              "type": "string",
              "example": "ap_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "accounting_period_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Accounting period IDs (`ap_…`), up to 100. Omit to return every period.",
            "style": "form",
            "explode": true
          },
          {
            "name": "verbosity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["faithful", "compact"],
              "default": "faithful"
            },
            "description": "`faithful` (the default) returns all fields. `compact` returns the same figures in a smaller shape."
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Set to `true` to include every period from the first period through `end_date`. Requires `end_date`; `start_date`, `accounting_period_id` or `accounting_period_ids` return HTTP 400. Defaults to `false`."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BalanceSheet"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "ledger_accounts": [
                      {
                        "id": "lac_507f1f77bcf86cd799439011",
                        "name": "Cash",
                        "type": "Asset",
                        "normal_balance": "debit",
                        "sequence_number": 1000,
                        "parent_account_id": null,
                        "is_postable": true,
                        "is_clearing_account": false,
                        "is_archived": false,
                        "archived_at": null,
                        "asset_type": null,
                        "created_at": "2026-08-31T12:00:00Z"
                      }
                    ],
                    "balances": {
                      "lac_507f1f77bcf86cd799439011": {
                        "2026-08": {
                          "credit_debit": {
                            "opening_balance": {
                              "value": "0.00"
                            },
                            "closing_balance": {
                              "value": "0.00"
                            },
                            "current_balance": {
                              "value": "0.00"
                            },
                            "debits": {
                              "value": "0.00"
                            },
                            "credits": {
                              "value": "0.00"
                            },
                            "accounting_period_start_date_utc": null,
                            "legal_entity_ids": ["le_507f1f77bcf86cd799439011"]
                          },
                          "tag_balance": {
                            "value": "0.00"
                          }
                        }
                      }
                    },
                    "data_quality": {
                      "negative_asset_periods": [
                        {
                          "period": "2026-09",
                          "total": "100.00"
                        }
                      ],
                      "unbalanced_periods": [
                        {
                          "period": "2026-09",
                          "assets": "100.00",
                          "liabilities_plus_equity": "90.00",
                          "difference": "10.00"
                        }
                      ],
                      "warnings": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/trial-balance": {
      "get": {
        "operationId": "get_trial_balance",
        "summary": "Get trial balance",
        "description": "Returns cumulative balances: opening balance plus activity through the ending period. Provide start_date and end_date; a window with no matching periods is rejected.",
        "tags": ["Trial Balance"],
        "parameters": [
          {
            "name": "tag_id",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prefixed tag ID (`tag_`) for segment filtering."
          },
          {
            "name": "include_zero_rows",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "Set to `false` to omit accounts with no balance or movement. Defaults to `true`. Totals always cover all accounts."
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "description": "Inclusive interval start. Required unless `as_of` is `true`; omit it when `as_of` is `true`.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "end_date",
            "in": "query",
            "required": true,
            "description": "Inclusive interval end; start must not exceed end.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "verbosity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["faithful", "compact"],
              "default": "faithful"
            },
            "description": "`compact` returns the account ID, hierarchy and normal-balance fields. `faithful` returns all account fields. The figures are the same."
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Set to `true` to include every period from the first period through `end_date`. Requires `end_date`; `start_date` returns HTTP 400. Defaults to `false`."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TrialBalance"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "meta": {
                      "zero_rows_omitted": false,
                      "account_count": 0,
                      "total_account_count": 0
                    },
                    "ledger_accounts": [
                      {
                        "id": "lac_507f1f77bcf86cd799439011",
                        "name": "Cash",
                        "type": "Asset",
                        "normal_balance": "debit",
                        "sequence_number": 1000,
                        "parent_account_id": null,
                        "is_postable": true,
                        "is_clearing_account": false,
                        "is_archived": false,
                        "archived_at": null,
                        "asset_type": null,
                        "created_at": "2026-08-31T12:00:00Z"
                      }
                    ],
                    "balances": [
                      {
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "opening_balance": "0.00",
                        "closing_balance": "0.00",
                        "current_balance": "0.00",
                        "debits": "0.00",
                        "credits": "0.00"
                      }
                    ],
                    "data_quality": {
                      "is_balanced": false,
                      "is_empty": false,
                      "total_debits": "100.00",
                      "total_credits": "100.00",
                      "warnings": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/closing-positions": {
      "get": {
        "operationId": "get_closing_positions",
        "summary": "Get closing positions",
        "description": "Return end-of-period quantities, valuations and data-quality warnings.",
        "tags": ["Closing Positions"],
        "parameters": [
          {
            "name": "financial_account_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Prefixed financial account IDs (`fac_`). Up to 100 IDs.",
            "style": "form",
            "explode": true
          },
          {
            "name": "asset_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Asset types to include.",
            "style": "form",
            "explode": true
          },
          {
            "name": "source_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Source IDs to include.",
            "style": "form",
            "explode": true
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "description": "Reporting date. Omit to return current positions.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "include_zero_rows",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["true", "false"]
            },
            "description": "Include rows where quantity, cost_basis, market_value, and unrealized_gain are all zero. Default: `true` (include). Set to `false` to drop zero-balance positions."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClosingPosition"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "description": "Total positions across all pages after filtering."
                    },
                    "data_quality": {
                      "type": "object",
                      "description": "Checks all positions in the requested scope before pagination and fiat-row filtering. A clean filtered result does not certify the whole organization.",
                      "properties": {
                        "has_negative_positions": {
                          "type": "boolean",
                          "description": "True when any position holds a negative quantity."
                        },
                        "negative_positions": {
                          "type": "array",
                          "description": "Up to 25 negative positions. Use negative_position_count for the full count.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "token": {
                                "type": "string",
                                "description": "Asset symbol."
                              },
                              "quantity": {
                                "type": "string",
                                "description": "The impossible quantity, at full precision."
                              },
                              "market_value": {
                                "type": "string",
                                "description": "That row's market value (2 decimal places), for sizing the discrepancy."
                              }
                            }
                          }
                        },
                        "negative_market_value": {
                          "type": "string",
                          "description": "Signed market-value sum for measurable negative positions. If unmeasured_position_count is nonzero, the total is incomplete."
                        },
                        "negative_position_count": {
                          "type": "integer",
                          "description": "Negative positions before the display cap."
                        },
                        "unmeasured_position_count": {
                          "type": "integer",
                          "description": "Negative positions with an unmeasurable market value. Their financial impact is unknown."
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "`[WARNING]`-prefixed prose. Non-empty means these figures must not be presented as reconciled."
                        }
                      },
                      "required": [
                        "has_negative_positions",
                        "negative_positions",
                        "negative_position_count",
                        "negative_market_value",
                        "unmeasured_position_count",
                        "warnings"
                      ]
                    }
                  },
                  "required": ["data", "has_more", "next_cursor", "total_count", "data_quality"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "token": "ETH",
                      "quantity": "100.00",
                      "cost_basis": "100.00",
                      "weighted_average_cost": "2500.00",
                      "current_price": "100.00",
                      "market_value": "100.00",
                      "unrealized_gain": "100.00",
                      "date": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "total_count": 1,
                  "data_quality": {
                    "has_negative_positions": false,
                    "negative_positions": [],
                    "negative_position_count": 0,
                    "negative_market_value": "0.00",
                    "unmeasured_position_count": 0,
                    "warnings": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/treasury-balances": {
      "get": {
        "operationId": "get_treasury_balances",
        "summary": "Get treasury balances",
        "description": "Return treasury balances for now or an `as_of` date, grouped by source with each source’s tokens. Historical coverage varies by source; read `context.warnings` for unavailable data. The only supported basis is `live`. For posted ledger balances, use the balance sheet or trial balance report. If some sources fail, the response returns HTTP 200 and identifies those sources in `context.warnings`.",
        "tags": ["Treasury Balances"],
        "parameters": [
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Ignored. All figures are in USD, and `context.currency` is always `USD`.",
            "schema": {
              "type": "string",
              "example": "USD"
            }
          },
          {
            "name": "include_zero",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include zero balances. By default, zero and very small balances are hidden.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "description": "Date of a past position (YYYY-MM-DD). Omit for the live position. Bank balances are not included for a past date. Future dates return HTTP 400.",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-08-31"
            }
          },
          {
            "name": "basis",
            "in": "query",
            "required": true,
            "description": "Only `live` is supported.",
            "schema": {
              "type": "string",
              "enum": ["live"]
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`)."
              },
              "minItems": 1,
              "maxItems": 100
            },
            "description": "Legal entities to include.",
            "style": "form",
            "explode": true
          },
          {
            "name": "financial_account_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Source ID (`fac_…`)."
              },
              "minItems": 1,
              "maxItems": 100
            },
            "description": "Wallet and Plaid source IDs. For exchanges, use `exchange_source_ids`.",
            "style": "form",
            "explode": true
          },
          {
            "name": "exchange_source_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Exchange source ID (`exs_…`)."
              },
              "minItems": 1,
              "maxItems": 100
            },
            "description": "Legal entities to include.",
            "style": "form",
            "explode": true
          },
          {
            "name": "addresses",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "maxItems": 100
            },
            "description": "On-chain filter. It does not filter bank or exchange balances.",
            "style": "form",
            "explode": true
          },
          {
            "name": "chains",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "maxItems": 100
            },
            "description": "On-chain filter. It does not filter bank or exchange balances.",
            "style": "form",
            "explode": true
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded. Sources that could not be read are listed in `context.warnings`.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TreasuryBalance"
                      },
                      "description": "The records."
                    },
                    "context": {
                      "type": "object",
                      "properties": {
                        "requested_at": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Time of the request."
                        },
                        "as_of": {
                          "type": ["string", "null"],
                          "description": "Echo of the requested `as_of`, or null for a live position."
                        },
                        "data_as_of": {
                          "type": ["string", "null"],
                          "format": "date-time",
                          "description": "Oldest provider update time across the returned rows; null when unknown or empty."
                        },
                        "currency": {
                          "type": "string",
                          "example": "USD",
                          "description": "Currency of the values."
                        },
                        "basis": {
                          "type": "string",
                          "enum": ["live"],
                          "description": "Balance basis of the report."
                        },
                        "total_fiat": {
                          "type": "string",
                          "example": "790280.42",
                          "description": "Total value in `currency` (decimal string)."
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/TreasuryBalancesWarning"
                          },
                          "description": "Sources that could not be read."
                        }
                      },
                      "required": [
                        "requested_at",
                        "as_of",
                        "data_as_of",
                        "currency",
                        "basis",
                        "total_fiat",
                        "warnings"
                      ],
                      "description": "Report context."
                    },
                    "bank_balances": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BankCashBalance"
                      },
                      "description": "Bank balances."
                    }
                  },
                  "required": ["data", "context", "bank_balances"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "source_id": "fac_507f1f77bcf86cd799439011",
                      "source_class": "crypto",
                      "chain": "eth",
                      "provider": null,
                      "alias": "Entendre Finance Safe",
                      "entity_name": "Entendre Finance Inc.",
                      "legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "total_fiat": "100.00",
                      "tokens": [
                        {
                          "symbol": "ETH",
                          "balance": "0.05",
                          "fiat_value": "100.00",
                          "is_native": true
                        }
                      ],
                      "as_of": "2026-08-31T12:00:00Z",
                      "basis": "live",
                      "availability": "available",
                      "warnings": []
                    }
                  ],
                  "context": {
                    "requested_at": "2026-08-31T12:00:05Z",
                    "as_of": null,
                    "data_as_of": "2026-08-31T12:00:00Z",
                    "currency": "USD",
                    "basis": "live",
                    "total_fiat": "100.00",
                    "warnings": []
                  },
                  "bank_balances": []
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/realized-gains": {
      "get": {
        "operationId": "get_realized_gains_and_losses",
        "summary": "Get realized gains & losses",
        "description": "Return proceeds, cost basis, and realized gains or losses for the disposal period. The report includes its calculation method.",
        "tags": ["Realized Gains & Losses"],
        "parameters": [
          {
            "name": "accounting_period_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Any of these accounting period IDs. Omit to include all periods within the other filters.",
            "style": "form",
            "explode": true
          },
          {
            "name": "asset_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Asset type filters (such as `ETH`, `USDC`). Omit to include every asset type.",
            "style": "form",
            "explode": true
          },
          {
            "name": "summary",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include totals across all matching pages, grouped by currency. If totals cannot be calculated, the request fails."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RealizedGains"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "summary": {
                      "$ref": "#/components/schemas/RealizedGainsSummary"
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "asset_type": "ETH",
                      "asset_record": "ast_507f1f77bcf86cd799439011",
                      "date_received": "2026-08-01T00:00:00Z",
                      "quantity": "100.00",
                      "remaining_quantity": "0.00",
                      "cost_basis": "100.00",
                      "currency": "USD",
                      "disposals": [
                        {
                          "sale_date": "2026-08-31T12:00:00Z",
                          "quantity_sold": "100.00",
                          "sale_price": "110.00"
                        }
                      ]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "summary": {
                    "methodology": "per_unit_cost_basis_approximation",
                    "by_currency": [
                      {
                        "currency": "USD",
                        "total_proceeds": "11000.00",
                        "total_cost_basis": "10000.00",
                        "total_gain": "1000.00",
                        "short_term_gain": "1000.00",
                        "long_term_gain": "0.00",
                        "disposal_count": 1,
                        "sold_asset_count": 1
                      }
                    ],
                    "currency": "USD",
                    "total_proceeds": "11000.00",
                    "total_cost_basis": "10000.00",
                    "total_gain": "1000.00",
                    "short_term_gain": "1000.00",
                    "long_term_gain": "0.00",
                    "disposal_count": 1,
                    "sold_asset_count": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/asset-tax-lots": {
      "get": {
        "operationId": "get_asset_tax_lots",
        "summary": "Get asset tax lots",
        "description": "Returns acquisition lots, remaining quantities, cost basis and linked dispositions.",
        "tags": ["Asset Tax Lots"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "asset_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Filter by asset type (e.g., `ETH`, `BTC`).",
            "style": "form",
            "explode": true
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "description": "Snapshot date. Required.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TaxLot"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "context": {
                      "$ref": "#/components/schemas/ReportContext"
                    }
                  },
                  "required": ["data", "has_more", "next_cursor", "context"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "asset_id": "ast_507f1f77bcf86cd799439011",
                      "asset_type": "ETH",
                      "source_id": null,
                      "date_received": "2026-08-31T12:00:00Z",
                      "quantity": "100.00",
                      "remaining_quantity": "100.00",
                      "cost_basis": "100.00",
                      "remaining_cost_basis": "100.00",
                      "currency": "USD",
                      "method": "FIFO",
                      "disposition_ids": ["ref_507f1f77bcf86cd799439011"]
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "context": {
                    "start_date": "2026-08-01T00:00:00Z",
                    "end_date": "2026-08-31T23:59:59.999Z",
                    "as_of": null,
                    "currency": "USD",
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "basis": "ledger",
                    "generated_at": "2026-08-31T12:00:00Z",
                    "warnings": [],
                    "date_boundary": "inclusive_end"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/schedule-of-dispositions": {
      "get": {
        "operationId": "get_schedule_of_dispositions",
        "summary": "Get schedule of dispositions",
        "description": "Return asset disposals with dates, quantities, proceeds and cost basis. Each disposal includes links to its transaction and acquisition lot.",
        "tags": ["Schedule of Dispositions"],
        "parameters": [
          {
            "name": "accounting_period_ids",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Any of these accounting period IDs. Omit to include all periods within the other filters.",
            "style": "form",
            "explode": true
          },
          {
            "name": "asset_types",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Asset types to include.",
            "style": "form",
            "explode": true
          },
          {
            "name": "summary",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include totals across all matching pages, grouped by currency. If totals cannot be calculated, the request fails."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Filter by one or more legal entity IDs. Omit to include all authorized entities. An empty list is invalid."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Disposition"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "summary": {
                      "$ref": "#/components/schemas/RealizedGainsSummary"
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "asset_type": "ETH",
                      "asset_record": "ast_507f1f77bcf86cd799439011",
                      "date_received": "2026-08-01T00:00:00Z",
                      "quantity": "100.00",
                      "remaining_quantity": "0.00",
                      "cost_basis": "100.00",
                      "disposals": [
                        {
                          "sale_date": "2026-08-31T12:00:00Z",
                          "quantity_sold": "100.00",
                          "sale_price": "110.00"
                        }
                      ],
                      "currency": "USD"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "summary": {
                    "methodology": "per_unit_cost_basis_approximation",
                    "by_currency": [
                      {
                        "currency": "USD",
                        "total_proceeds": "11000.00",
                        "total_cost_basis": "10000.00",
                        "total_gain": "1000.00",
                        "short_term_gain": "1000.00",
                        "long_term_gain": "0.00",
                        "disposal_count": 1,
                        "sold_asset_count": 1
                      }
                    ],
                    "currency": "USD",
                    "total_proceeds": "11000.00",
                    "total_cost_basis": "10000.00",
                    "total_gain": "1000.00",
                    "short_term_gain": "1000.00",
                    "long_term_gain": "0.00",
                    "disposal_count": 1,
                    "sold_asset_count": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/reports/financial-insights": {
      "get": {
        "operationId": "get_financial_insights",
        "summary": "Get financial insights",
        "description": "Returns selected financial metrics and their formulas, including revenue, profit, expenses, spending, burn rate, runway and cash flow. Not paginated — this is a computed report, not a resource list; request only the metrics a question needs.",
        "tags": ["Financial Insights"],
        "parameters": [
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "description": "Legal entity ID (`le_…`). Can be combined with `legal_entity_ids`.",
            "schema": {
              "type": "string",
              "example": "le_507f1f77bcf86cd799439011"
            }
          },
          {
            "name": "legal_entity_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Legal entity ID (`le_…`).",
                "example": "le_507f1f77bcf86cd799439011"
              },
              "maxItems": 100,
              "uniqueItems": true
            },
            "style": "form",
            "explode": true,
            "description": "Legal entities to include (`le_…`). Omit to include all."
          },
          {
            "name": "account_ids",
            "in": "query",
            "required": false,
            "description": "Comma-separated fac_ financial account IDs. Ignored when `basis=ledger`; `meta.account_ids_ignored` is then set.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": false
          },
          {
            "name": "start_date",
            "in": "query",
            "required": true,
            "description": "Inclusive interval start.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "end_date",
            "in": "query",
            "required": true,
            "description": "Inclusive interval end; start must not exceed end.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-08-31T12:00:00Z"
            }
          },
          {
            "name": "metrics",
            "in": "query",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Metric identifier.",
                "enum": ["revenue", "profit", "expenses", "spending", "burn_rate", "runway", "cash_flow"]
              },
              "minItems": 1,
              "maxItems": 7
            },
            "style": "form",
            "explode": true,
            "description": "Metrics to return."
          },
          {
            "name": "basis",
            "in": "query",
            "required": true,
            "description": "Required. `ledger` for the posted books, or `transactions` for observed cash movements.",
            "schema": {
              "type": "string",
              "enum": ["ledger", "transactions"]
            }
          },
          {
            "name": "granularity",
            "in": "query",
            "required": false,
            "description": "Bucket size. For `basis=ledger`, the response shows the monthly buckets used.",
            "schema": {
              "type": "string",
              "enum": ["daily", "weekly", "monthly"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Not paginated. Each item has its own `meta`. Burn rate and runway always use monthly buckets, whatever the `granularity`.",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FinancialInsight"
                      },
                      "description": "The records."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "metric": "expenses",
                      "value": "100.00",
                      "unit": "USD",
                      "formula": "sum(expense account balances)",
                      "reason": null,
                      "details": {
                        "total": "100.00",
                        "by_category": [
                          {
                            "category": "Software",
                            "amount": "100.00"
                          }
                        ],
                        "currency": "USD",
                        "time_series": [
                          {
                            "period_start": "2026-08-01T00:00:00Z",
                            "period_end": "2026-08-31T23:59:59.999Z",
                            "total": "100.00",
                            "categories": [
                              {
                                "category": "Software",
                                "amount": "100.00"
                              }
                            ]
                          }
                        ]
                      },
                      "meta": {
                        "source": "gl",
                        "granularity": "monthly",
                        "start_date": "2026-08-01T00:00:00Z",
                        "end_date": "2026-08-31T23:59:59.999Z",
                        "currency": "USD",
                        "granularity_note": null,
                        "period_snapped_note": null,
                        "account_ids_ignored": false,
                        "account_ids_ignored_reason": null,
                        "basis": "accrual",
                        "cash_basis_caveat": null
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Reporting",
        "x-access-class": "read"
      }
    },
    "/v1/agents": {
      "get": {
        "operationId": "list_agents",
        "summary": "List agents",
        "description": "Returns visible agents with their configuration, owner, reviewer, schedule and latest run state. Filter by agent IDs; results are ordered by name.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["agt_abc123"]
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Agent"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "const": false,
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": "null",
                      "description": "Always `null`: the list is not paginated."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "agt_abc123",
                      "name": "Monthly close assistant",
                      "agent_type": "custom",
                      "status": "paused",
                      "is_active": false,
                      "description": null,
                      "cron_expressions": [],
                      "schedule": [],
                      "triggers": [],
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "last_run_at": null,
                      "last_error_message": null,
                      "last_agent_run_status": null,
                      "owner_user_id": null,
                      "reviewer_user_id": null,
                      "month_end_review_behavior": "auto_complete",
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z",
                      "created_by": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_agent",
        "summary": "Create agent",
        "description": "Create an agent with task instructions and an optional schedule. Use Update agent to change its schedule.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Agent"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "agt_abc123",
                    "name": "Monthly close assistant",
                    "agent_type": "custom",
                    "status": "paused",
                    "is_active": false,
                    "description": null,
                    "cron_expressions": [],
                    "schedule": [],
                    "triggers": [],
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "last_run_at": null,
                    "last_error_message": null,
                    "last_agent_run_status": null,
                    "owner_user_id": null,
                    "reviewer_user_id": null,
                    "month_end_review_behavior": "auto_complete",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "created_by": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "description"],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Display name for the agent."
                  },
                  "description": {
                    "type": "string",
                    "description": "Human-readable description of what this agent should do."
                  },
                  "cron_expressions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Five-field cron expressions in the organization timezone, such as `0 2 * * *`."
                  },
                  "schedule_description": {
                    "type": "string",
                    "description": "Natural language schedule as an alternative to `cron_expressions` (such as \"every weekday at 9am\")."
                  },
                  "legal_entities": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["id", "name"],
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "Legal entity ID (`le_…`)."
                        },
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256,
                          "description": "Legal entity name."
                        }
                      }
                    },
                    "description": "Legal entities this agent operates on."
                  },
                  "sources": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["id", "name"],
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "Source ID."
                        },
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256,
                          "description": "Source name."
                        }
                      }
                    },
                    "description": "Financial account sources this agent operates on."
                  },
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    },
                    "description": "Email addresses for run notifications."
                  },
                  "slack_channel_id": {
                    "type": ["string", "null"],
                    "description": "Slack channel ID for notifications."
                  },
                  "owner_user_id": {
                    "type": ["string", "null"],
                    "description": "Owner (`usr_…`). Omit it or send `null` to make the creating user the owner. To clear the owner later, send `null` to Update agent."
                  },
                  "reviewer_user_id": {
                    "type": ["string", "null"],
                    "description": "Prefixed `usr_` id of the reviewer to assign. Omit to default to none; null clears the assignment."
                  },
                  "month_end_review_behavior": {
                    "type": "string",
                    "enum": ["auto_complete", "carry_over"],
                    "description": "`carry_over` (the default) keeps runs that wait for review pending at month end. `auto_complete` closes them."
                  },
                  "enabled_mcp_connection_ids": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "MCP connections that the agent can use. Omit for none."
                  }
                },
                "description": "Scheduling is optional. Omit scheduling fields to create an on-demand agent."
              },
              "example": {
                "name": "Monthly close assistant",
                "description": "Reviews the month-end close checklist.",
                "schedule_description": "Every month on the 2nd at 09:00"
              }
            }
          }
        }
      }
    },
    "/v1/agents/{agent_id}": {
      "patch": {
        "operationId": "update_agent",
        "summary": "Update agent",
        "description": "Updates the name, instructions, lifecycle status, schedule, owner, reviewer, or data scope. Send only the fields to change; omitted fields are left unchanged.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "ID of the agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "agt_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Agent"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "agt_abc123",
                    "name": "Monthly close assistant",
                    "agent_type": "custom",
                    "status": "paused",
                    "is_active": false,
                    "description": null,
                    "cron_expressions": [],
                    "schedule": [],
                    "triggers": [],
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "last_run_at": null,
                    "last_error_message": null,
                    "last_agent_run_status": null,
                    "owner_user_id": null,
                    "reviewer_user_id": null,
                    "month_end_review_behavior": "auto_complete",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "created_by": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Updated display name."
                  },
                  "description": {
                    "type": "string",
                    "description": "Updated free-text description."
                  },
                  "status": {
                    "type": "string",
                    "enum": ["active", "paused", "archived"],
                    "description": "Lifecycle status. Paused and archived agents cannot start new runs."
                  },
                  "is_active": {
                    "type": "boolean",
                    "deprecated": true,
                    "description": "Deprecated; use `status`. `false` pauses the agent and `true` activates it."
                  },
                  "cron_expressions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replacement schedule as cron expressions."
                  },
                  "schedule_description": {
                    "type": "string",
                    "description": "Human-readable schedule label."
                  },
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Notification email recipients."
                  },
                  "slack_channel_id": {
                    "type": ["string", "null"],
                    "description": "Slack channel id for notifications, or null to clear."
                  },
                  "owner_user_id": {
                    "type": ["string", "null"],
                    "description": "Prefixed `usr_` id of the owner to assign, or null to clear."
                  },
                  "reviewer_user_id": {
                    "type": ["string", "null"],
                    "description": "Prefixed `usr_` id of the reviewer to assign, or null to clear."
                  },
                  "month_end_review_behavior": {
                    "type": "string",
                    "enum": ["auto_complete", "carry_over"],
                    "description": "`carry_over` keeps runs that wait for review pending at month end. `auto_complete` closes them. Omit to keep the current value."
                  },
                  "legal_entities": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["id"],
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "Legal entity ID (`le_…`)."
                        },
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256,
                          "description": "Legal entity name."
                        }
                      }
                    },
                    "description": "Legal entities this agent works on. Replaces the current list, so send the full list as `[{ \"id\": \"le_…\" }]`. `name` is ignored."
                  },
                  "sources": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["id"],
                      "properties": {
                        "id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 128,
                          "description": "Source ID."
                        },
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 256,
                          "description": "Source name."
                        }
                      }
                    },
                    "description": "Sources this agent works on. Replaces the current list, so send the full list as `[{ \"id\": \"…\" }]`. `name` is ignored."
                  },
                  "enabled_mcp_connection_ids": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "MCP connections that the agent can use. Replaces the list; send `[]` to clear it."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete_agent",
        "summary": "Delete agent",
        "description": "Delete an inactive agent. Required run history and audit records are retained.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "ID of the agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "agt_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "privileged"
      }
    },
    "/v1/agents/{agent_id}/runs": {
      "post": {
        "operationId": "run_agent",
        "summary": "Run agent",
        "description": "Trigger a manual agent run. Optional input supplies the instruction for this run only; omitting it uses the configured execution message. Returns the saved run and status_url. Poll that URL for the final outcome. Only one run may be in progress per agent; a concurrent start returns 409. Requires write:agents and a user-owned API key or user session; ownerless keys receive 403.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "ID of the agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "agt_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted. Poll for the final outcome.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "description": "URL to retrieve the returned resource through its list endpoint.",
                "schema": {
                  "type": "string"
                },
                "example": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
              },
              "Retry-After": {
                "description": "Seconds to wait before you check the run status.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                },
                "example": 2
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentRun"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "run_xyz789",
                    "status": "in_progress",
                    "success_data": null,
                    "error_data": null,
                    "error_message": null,
                    "reviewed_by": null,
                    "reviewed_at": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "agent_id": "agt_507f1f77bcf86cd799439011",
                    "review": {
                      "status": "not_required",
                      "reviewer_user_id": null,
                      "review_url": null,
                      "reviewed_at": null
                    },
                    "result_links": [],
                    "status_url": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "write",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "input": {
                    "type": "string",
                    "description": "Instruction for this run only. Omit to use the configured execution message.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "Review unclassified September transactions and report the proposed changes."
                  }
                },
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      },
      "get": {
        "operationId": "list_agent_runs",
        "summary": "List agent runs",
        "description": "List this agent’s runs, newest first, including saved results and errors. Filters run_ids and status are applied before pagination. Continue with next_cursor using the same filters. Cursors anchor to the last timestamp and run ID, so concurrent new runs do not shift subsequent pages.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "ID of the agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "agt_507f1f77bcf86cd799439011"
          },
          {
            "name": "run_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["run_xyz789"]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Run status.",
            "schema": {
              "type": "string",
              "enum": ["in_progress", "pending_review", "success", "error", "skipped"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AgentRun"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "run_xyz789",
                      "status": "in_progress",
                      "success_data": null,
                      "error_data": null,
                      "error_message": null,
                      "reviewed_by": null,
                      "reviewed_at": null,
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z",
                      "agent_id": "agt_507f1f77bcf86cd799439011",
                      "review": {
                        "status": "not_required",
                        "reviewer_user_id": null,
                        "review_url": null,
                        "reviewed_at": null
                      },
                      "result_links": [],
                      "status_url": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "read"
      }
    },
    "/v1/agents/{agent_id}/runs/{run_id}/cancel": {
      "post": {
        "operationId": "cancel_agent_run",
        "summary": "Cancel agent run",
        "description": "Request that an agent run stop. Check `meta.cancellation_status`: `accepted` means the stop signal was confirmed; `pending` means it is not confirmed yet; `no_active_turn` and `no_session` mean no running turn was stopped; `owner_mismatch` means ownership could not be verified. Poll `status_url` for the final run state. Cancellation does not undo completed work. The reason is recorded in the organization audit log. Requires `write:agents` and a user-owned API key or a user session. Keys without an owner receive 403.",
        "tags": ["Agents"],
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "ID of the agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "agt_507f1f77bcf86cd799439011"
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "ID of the run.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "run_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "202": {
            "description": "Current run and cancellation outcome. Poll status_url for the final state.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "Location": {
                "description": "URL to retrieve the returned resource through its list endpoint.",
                "schema": {
                  "type": "string"
                },
                "example": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
              },
              "Retry-After": {
                "description": "Seconds to wait before you check the run status.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                },
                "example": 2
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentRun"
                    },
                    "meta": {
                      "type": "object",
                      "required": ["cancellation_status"],
                      "properties": {
                        "cancellation_status": {
                          "type": "string",
                          "enum": ["accepted", "pending", "no_active_turn", "no_session", "owner_mismatch"],
                          "description": "Result of the stop request, separate from the saved run status. Only `accepted` confirms that the stop signal was accepted."
                        }
                      },
                      "description": "Cancellation details."
                    }
                  },
                  "required": ["data", "meta"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "run_xyz789",
                    "status": "in_progress",
                    "success_data": null,
                    "error_data": null,
                    "error_message": null,
                    "reviewed_by": null,
                    "reviewed_at": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "agent_id": "agt_507f1f77bcf86cd799439011",
                    "review": {
                      "status": "not_required",
                      "reviewer_user_id": null,
                      "review_url": null,
                      "reviewed_at": null
                    },
                    "result_links": [],
                    "status_url": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
                  },
                  "meta": {
                    "cancellation_status": "accepted"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Agents",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Reason included in the organization audit event.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "Correct the selected accounting records."
                  }
                },
                "required": ["reason"],
                "additionalProperties": false
              },
              "example": {
                "reason": "Correct the selected accounting records."
              }
            }
          }
        }
      }
    },
    "/v1/integrations": {
      "get": {
        "operationId": "list_integrations",
        "summary": "List integrations",
        "description": "Returns one entry for each supported provider, connected or not: accounting (QuickBooks, Xero, NetSuite, DualEntry, Campfire, Intuit vendor login), cards (Ramp, Rain), receivables (Stripe, Request Finance), banking (Plaid), payroll (Finch), custody (Fireblocks) and communication (Gmail, Slack). Each entry has `connected`, the number of connections and each connection with its status and legal entity. A provider whose status could not be read has `unavailable: true`; its state is unknown, not disconnected. The status comes from the stored connection record. It is not a live check of the provider. The list is not paginated: `has_more` is always false.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "description": "Providers to return, separated by commas, for example `stripe,slack`: quickbooks, xero, netsuite, dualentry, campfire, intuit, ramp, raincards, stripe, requestfinance, plaid, finch, fireblocks, gmail or slack. An unknown value returns 400.",
            "schema": {
              "type": "string"
            },
            "example": "stripe,slack"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Categories to return, separated by commas: accounting, cards, banking, payroll, receivables, custody or communication. With `provider`, a provider must match both filters. An unknown value returns 400.",
            "schema": {
              "type": "string"
            },
            "example": "accounting"
          },
          {
            "name": "connected",
            "in": "query",
            "required": false,
            "description": "When true, return only providers with an active connection. When false, only providers without one. Providers with `unavailable: true` are not returned by either value.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "description": "Return only connections of this legal entity. An ID that is not in your organization returns 404. Providers whose connections have no legal entity return no connections.",
            "schema": {
              "type": "string"
            },
            "example": "le_507f1f77bcf86cd799439012"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Accepted for a uniform list call and ignored: this list has no pagination.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Accepted for a uniform list call and ignored: this list has no pagination.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Integration"
                      },
                      "description": "One entry per provider."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Always false. The list is not paginated."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Always null. The list is not paginated."
                    },
                    "total_count": {
                      "type": "integer",
                      "description": "Number of providers returned."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor", "total_count"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "provider": "stripe",
                      "category": "receivables",
                      "connected": true,
                      "count": 1,
                      "connections": [
                        {
                          "id": "sar_507f1f77bcf86cd799439011",
                          "status": "active",
                          "legal_entity_id": "le_507f1f77bcf86cd799439012",
                          "legal_entity_name": "Acme Inc",
                          "external_id": "acct_1Nxyz",
                          "external_name": "Acme Inc",
                          "connected_at": "2026-03-02T10:15:00.000Z",
                          "last_activity_at": "2026-09-20T08:00:00.000Z"
                        }
                      ]
                    },
                    {
                      "provider": "slack",
                      "category": "communication",
                      "connected": false,
                      "count": 0,
                      "connections": []
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "total_count": 2
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      }
    },
    "/v1/connections": {
      "get": {
        "operationId": "list_connections",
        "summary": "List connections",
        "description": "Returns connection configuration, source references, capabilities and setup status. Filter by connection IDs or status. Credentials are never returned.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "connection_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. The other filters also apply.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 100,
              "uniqueItems": true
            },
            "example": ["con_507f1f77bcf86cd799439011"]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Connection status.",
            "schema": {
              "type": "string",
              "enum": ["pending_setup", "active", "expired", "disconnecting", "disconnected", "failed"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Connection"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "con_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "provider": "quickbooks",
                      "auth_method": "oauth",
                      "name": "Operating bank connection",
                      "status": "pending_setup",
                      "external_account_id": null,
                      "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                      "source_ids": [],
                      "capabilities": ["import_transactions"],
                      "authorization_attempt": {
                        "id": "auth_507f1f77bcf86cd799439011",
                        "status": "pending",
                        "setup_url": "https://app.entendre.finance/settings/integrations",
                        "expires_at": "2026-08-31T12:10:00Z",
                        "error": null
                      },
                      "created_at": "2026-08-31T12:00:00Z",
                      "guidance": {
                        "allowed_actions": [],
                        "warnings": [],
                        "version": "v_example"
                      },
                      "revocation_error": null,
                      "retained_resources": ["transactions"],
                      "etag": "\"v_example\""
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "connect_provider",
        "summary": "Connect provider",
        "description": "Connects an exchange, Plaid, Ramp or general-ledger provider. The body depends on the provider.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "OAuth consent URL for a hosted GL provider (data.redirect_url).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "type": "object",
                          "required": ["redirect_url"],
                          "properties": {
                            "redirect_url": {
                              "type": "string",
                              "description": "Provider consent URL. Open it to authorize the connection."
                            }
                          },
                          "description": "The connection."
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Connection"
                        },
                        "warning": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Warning about the connection, such as a partial import."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "data": {
                    "id": "con_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "provider": "quickbooks",
                    "auth_method": "oauth",
                    "name": "QuickBooks accounting",
                    "status": "pending_setup",
                    "external_account_id": null,
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "source_ids": [],
                    "capabilities": ["import_transactions"],
                    "authorization_attempt": {
                      "id": "auth_507f1f77bcf86cd799439011",
                      "status": "pending",
                      "setup_url": "https://app.entendre.finance/settings/integrations",
                      "expires_at": "2026-08-31T12:10:00Z",
                      "error": null
                    },
                    "created_at": "2026-08-31T12:00:00Z",
                    "guidance": {
                      "allowed_actions": [],
                      "warnings": [],
                      "version": "v_example"
                    },
                    "revocation_error": null,
                    "retained_resources": ["transactions"],
                    "etag": "\"v_example\""
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Version tag of the returned resource.",
                "schema": {
                  "type": "string"
                },
                "example": "\"v_example\""
              },
              "Location": {
                "description": "URL to retrieve the returned resource through its list endpoint.",
                "schema": {
                  "type": "string"
                },
                "example": "/v1/connections?connection_ids=con_507f1f77bcf86cd799439011"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Connection"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "con_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "provider": "quickbooks",
                    "auth_method": "oauth",
                    "name": "QuickBooks accounting",
                    "status": "pending_setup",
                    "external_account_id": null,
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "source_ids": [],
                    "capabilities": ["import_transactions"],
                    "authorization_attempt": {
                      "id": "auth_507f1f77bcf86cd799439011",
                      "status": "pending",
                      "setup_url": "https://app.entendre.finance/settings/integrations",
                      "expires_at": "2026-08-31T12:10:00Z",
                      "error": null
                    },
                    "created_at": "2026-08-31T12:00:00Z",
                    "guidance": {
                      "allowed_actions": [],
                      "warnings": [],
                      "version": "v_example"
                    },
                    "revocation_error": null,
                    "retained_resources": ["transactions"],
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "secure_setup",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "title": "Exchange",
                    "type": "object",
                    "description": "An exchange venue. Credentials are supplied inline; there is no hosted setup for an exchange.",
                    "required": ["provider", "name", "legal_entity_ids", "api_key", "api_secret"],
                    "additionalProperties": false,
                    "properties": {
                      "provider": {
                        "type": "string",
                        "description": "The exchange venue in lower case, such as kraken or binance. For QuickBooks, Xero, NetSuite, Campfire and DualEntry, use the general-ledger request body.",
                        "example": "kraken"
                      },
                      "name": {
                        "type": "string",
                        "description": "Display name. Required for an exchange connection.",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "legal_entity_ids": {
                        "type": "array",
                        "description": "Exactly one legal entity. An exchange connection scopes to a single entity.",
                        "items": {
                          "type": "string",
                          "description": "Legal entity ID (`le_…`).",
                          "example": "le_507f1f77bcf86cd799439011"
                        },
                        "minItems": 1,
                        "maxItems": 1,
                        "uniqueItems": true
                      },
                      "api_key": {
                        "type": "string",
                        "description": "Venue API key.",
                        "minLength": 1
                      },
                      "api_secret": {
                        "type": "string",
                        "description": "Venue API secret.",
                        "minLength": 1
                      },
                      "api_passphrase": {
                        "type": "string",
                        "description": "Venue API passphrase. Required for coinbase, coinbase_exchange, coinbase_prime, coinbase_international and kucoin; omitting it there fails with 400.",
                        "minLength": 1
                      },
                      "return_url": {
                        "type": "string",
                        "description": "Registered HTTPS dashboard URL to return to after hosted setup.",
                        "format": "uri",
                        "example": "https://app.entendre.finance/settings/integrations"
                      }
                    }
                  },
                  {
                    "title": "Bank",
                    "type": "object",
                    "description": "A Plaid bank account. Omit public_token to receive a hosted setup URL, or supply one to finish a link the client already completed.",
                    "required": ["provider"],
                    "additionalProperties": false,
                    "properties": {
                      "provider": {
                        "type": "string",
                        "enum": ["plaid"],
                        "description": "Always plaid."
                      },
                      "name": {
                        "type": "string",
                        "description": "Display name.",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "legal_entity_ids": {
                        "type": "array",
                        "description": "At most one legal entity.",
                        "items": {
                          "type": "string",
                          "description": "Legal entity ID (`le_…`).",
                          "example": "le_507f1f77bcf86cd799439011"
                        },
                        "minItems": 1,
                        "maxItems": 1,
                        "uniqueItems": true
                      },
                      "public_token": {
                        "type": "string",
                        "description": "Plaid public token from a completed Link session. Omit it to use hosted setup instead.",
                        "minLength": 1
                      },
                      "return_url": {
                        "type": "string",
                        "description": "Registered HTTPS dashboard URL to return to after hosted setup.",
                        "format": "uri",
                        "example": "https://app.entendre.finance/settings/integrations"
                      }
                    }
                  },
                  {
                    "title": "Card",
                    "type": "object",
                    "description": "A Ramp card program. Omit credentials to receive a hosted setup URL, or supply the app credentials inline.",
                    "required": ["provider"],
                    "additionalProperties": false,
                    "properties": {
                      "provider": {
                        "type": "string",
                        "enum": ["ramp"],
                        "description": "Always ramp."
                      },
                      "name": {
                        "type": "string",
                        "description": "Display name.",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "legal_entity_ids": {
                        "type": "array",
                        "description": "At most one legal entity.",
                        "items": {
                          "type": "string",
                          "description": "Legal entity ID (`le_…`).",
                          "example": "le_507f1f77bcf86cd799439011"
                        },
                        "minItems": 1,
                        "maxItems": 1,
                        "uniqueItems": true
                      },
                      "credentials": {
                        "type": "object",
                        "description": "Ramp application credentials. Omit them to use hosted setup instead.",
                        "required": ["client_id", "client_secret"],
                        "additionalProperties": false,
                        "properties": {
                          "client_id": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Ramp client ID."
                          },
                          "client_secret": {
                            "type": "string",
                            "minLength": 1,
                            "description": "Ramp client secret."
                          }
                        }
                      },
                      "return_url": {
                        "type": "string",
                        "description": "Registered HTTPS dashboard URL to return to after hosted setup.",
                        "format": "uri",
                        "example": "https://app.entendre.finance/settings/integrations"
                      }
                    }
                  },
                  {
                    "title": "Rain",
                    "type": "object",
                    "description": "A Rain card program for one legal entity. Cards are imported on a schedule. A duplicate key for the same legal entity returns HTTP 409.",
                    "required": ["provider", "legal_entity_ids", "api_key"],
                    "additionalProperties": false,
                    "properties": {
                      "provider": {
                        "type": "string",
                        "enum": ["rain"],
                        "description": "Always rain."
                      },
                      "name": {
                        "type": "string",
                        "description": "Display name.",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "legal_entity_ids": {
                        "type": "array",
                        "description": "Exactly one legal entity.",
                        "items": {
                          "type": "string",
                          "description": "Legal entity ID (`le_…`).",
                          "example": "le_507f1f77bcf86cd799439011"
                        },
                        "minItems": 1,
                        "maxItems": 1,
                        "uniqueItems": true
                      },
                      "api_key": {
                        "type": "string",
                        "description": "Rain API key.",
                        "minLength": 1
                      }
                    }
                  },
                  {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/V1GLConnectQuickBooks"
                      },
                      {
                        "$ref": "#/components/schemas/V1GLConnectXero"
                      },
                      {
                        "$ref": "#/components/schemas/V1GLConnectNetSuite"
                      },
                      {
                        "$ref": "#/components/schemas/V1GLConnectDualEntry"
                      },
                      {
                        "$ref": "#/components/schemas/V1GLConnectCampfire"
                      }
                    ],
                    "discriminator": {
                      "propertyName": "provider",
                      "mapping": {
                        "quickbooks": "#/components/schemas/V1GLConnectQuickBooks",
                        "xero": "#/components/schemas/V1GLConnectXero",
                        "netsuite": "#/components/schemas/V1GLConnectNetSuite",
                        "dualentry": "#/components/schemas/V1GLConnectDualEntry",
                        "campfire": "#/components/schemas/V1GLConnectCampfire"
                      }
                    }
                  }
                ]
              },
              "example": {
                "provider": "kraken",
                "name": "Kraken main",
                "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                "api_key": "ek_live_...",
                "api_secret": "..."
              }
            }
          }
        }
      }
    },
    "/v1/connections/{connection_id}": {
      "patch": {
        "operationId": "update_connection",
        "summary": "Update connection",
        "description": "Updates the connection name or legal-entity scope. Change credentials through Reauthorize connection.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "description": "Optional. The `etag` from List connections. A stale value returns HTTP 412.",
            "schema": {
              "type": "string"
            },
            "example": "\"v_example\""
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Version tag of the returned resource.",
                "schema": {
                  "type": "string"
                },
                "example": "\"v_example\""
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Connection"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "con_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "provider": "quickbooks",
                    "auth_method": "oauth",
                    "name": "Operating bank connection",
                    "status": "pending_setup",
                    "external_account_id": null,
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "source_ids": [],
                    "capabilities": ["import_transactions"],
                    "authorization_attempt": {
                      "id": "auth_507f1f77bcf86cd799439011",
                      "status": "pending",
                      "setup_url": "https://app.entendre.finance/settings/integrations",
                      "expires_at": "2026-08-31T12:10:00Z",
                      "error": null
                    },
                    "created_at": "2026-08-31T12:00:00Z",
                    "guidance": {
                      "allowed_actions": [],
                      "warnings": [],
                      "version": "v_example"
                    },
                    "revocation_error": null,
                    "retained_resources": ["transactions"],
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` is missing, or the resource changed after you read it. Read it again, then decide whether to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PRECONDITION_FAILED",
                    "message": "The resource changed. Read it again before you update it.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Display name.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "Operating bank connection"
                  },
                  "legal_entity_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "Legal entity ID (`le_…`).",
                      "example": "le_507f1f77bcf86cd799439011"
                    },
                    "maxItems": 100,
                    "uniqueItems": true,
                    "description": "Legal entities (`le_…`)."
                  }
                },
                "additionalProperties": false,
                "minProperties": 1
              },
              "example": {
                "name": "Operating bank connection",
                "legal_entity_ids": ["le_507f1f77bcf86cd799439011"]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "disconnect_provider",
        "summary": "Disconnect provider",
        "description": "Disconnect the provider and stop future imports. Cleanup depends on the provider. Plaid soft-deletes linked accounts and transactions; journal entries remain. A successful local cleanup does not by itself establish remote credential revocation.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "description": "Optional. The `etag` from List connections. A stale value returns HTTP 412.",
            "schema": {
              "type": "string"
            },
            "example": "\"v_example\""
          }
        ],
        "responses": {
          "200": {
            "description": "The connection is disconnected. The response shows its state, the cleanup and any revocation error.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "ETag": {
                "description": "Version tag of the returned resource.",
                "schema": {
                  "type": "string"
                },
                "example": "\"v_example\""
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Connection"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "con_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "provider": "quickbooks",
                    "auth_method": "oauth",
                    "name": "Operating bank connection",
                    "status": "disconnected",
                    "external_account_id": null,
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "source_ids": [],
                    "capabilities": ["import_transactions"],
                    "created_at": "2026-08-31T12:00:00Z",
                    "guidance": {
                      "allowed_actions": [],
                      "warnings": [],
                      "version": "v_example"
                    },
                    "revocation_error": null,
                    "retained_resources": ["transactions"],
                    "authorization_attempt": {
                      "id": "auth_507f1f77bcf86cd799439011",
                      "status": "succeeded",
                      "setup_url": null,
                      "expires_at": null,
                      "error": null
                    },
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` is missing, or the resource changed after you read it. Read it again, then decide whether to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PRECONDITION_FAILED",
                    "message": "The resource changed. Read it again before you update it.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged"
      }
    },
    "/v1/connections/{connection_id}/reauthorize": {
      "post": {
        "operationId": "reauthorize_connection",
        "summary": "Reauthorize connection",
        "description": "Renews authorization for the same provider account. Supply replacement credentials inline for an exchange, or omit them to receive a secure setup URL. Track the authorization attempt on the connection. A different account needs a new connection.",
        "tags": ["Connections"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Connection"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "con_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "provider": "quickbooks",
                    "auth_method": "oauth",
                    "name": "Operating bank connection",
                    "status": "pending_setup",
                    "external_account_id": null,
                    "legal_entity_ids": ["le_507f1f77bcf86cd799439011"],
                    "source_ids": [],
                    "capabilities": ["import_transactions"],
                    "authorization_attempt": {
                      "id": "auth_507f1f77bcf86cd799439011",
                      "status": "pending",
                      "setup_url": "https://app.entendre.finance/settings/integrations",
                      "expires_at": "2026-08-31T12:10:00Z",
                      "error": null
                    },
                    "created_at": "2026-08-31T12:00:00Z",
                    "guidance": {
                      "allowed_actions": [],
                      "warnings": [],
                      "version": "v_example"
                    },
                    "revocation_error": null,
                    "retained_resources": ["transactions"],
                    "etag": "\"v_example\""
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "secure_setup",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "return_url": {
                    "type": "string",
                    "description": "Registered HTTPS return URL.",
                    "format": "uri",
                    "example": "https://app.entendre.finance/settings/integrations"
                  },
                  "api_key": {
                    "type": "string",
                    "description": "Replacement venue API key.",
                    "minLength": 1
                  },
                  "api_secret": {
                    "type": "string",
                    "description": "Replacement venue API secret.",
                    "minLength": 1
                  },
                  "api_passphrase": {
                    "type": "string",
                    "description": "Replacement venue API passphrase, for coinbase, coinbase_exchange, coinbase_prime, coinbase_international and kucoin.",
                    "minLength": 1
                  }
                },
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/connections/{connection_id}/external-accounts": {
      "get": {
        "operationId": "list_external_ledger_accounts",
        "summary": "List external ledger accounts",
        "description": "Lists the connected accounting system’s cached chart of accounts, including external IDs, account types and hierarchy.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/V1ExternalAccount"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "external_id": "42",
                      "name": "Operating bank connection",
                      "account_number": null,
                      "parent_account": null,
                      "description": null,
                      "account_type": null,
                      "classification": null,
                      "integration_type": null,
                      "eliminate": false,
                      "realm_id": "ref_507f1f77bcf86cd799439011",
                      "account_sub_type": null,
                      "ledger_account_sequence": null,
                      "created_at": null,
                      "updated_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      }
    },
    "/v1/connections/{connection_id}/external-entities": {
      "get": {
        "operationId": "list_external_legal_entities",
        "summary": "List external legal entities",
        "description": "List legal entities or subsidiaries available through this ERP connection.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": ["string", "null"]
            },
            "description": "Filter by entity status in the general ledger."
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/V1ExternalEntity"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "external_id": "1",
                      "entity_name": "Example Company",
                      "address": null,
                      "currency": null,
                      "integration_type": null,
                      "realm_id": "ref_507f1f77bcf86cd799439011",
                      "entity_type": null,
                      "status": null,
                      "created_at": null,
                      "updated_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      }
    },
    "/v1/connections/{connection_id}/account-mappings": {
      "get": {
        "operationId": "list_account_mappings",
        "summary": "List account mappings",
        "description": "List Entendre-to-ERP ledger account mappings for this connection and their validation status.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AccountMapping"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Mappings on this connection."
                    }
                  },
                  "required": ["count", "data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "glm_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "integration_type": "quickbooks",
                      "realm_id": "9341455734745729",
                      "internal_ledger_account_id": "lac_507f1f77bcf86cd799439011",
                      "external_ledger_account_id": "42",
                      "created_at": "2026-08-22T12:40:37.874Z",
                      "updated_at": "2026-08-31T03:49:29.365Z"
                    }
                  ],
                  "count": 1,
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      }
    },
    "/v1/connections/{connection_id}/account-mappings/{ledger_account_id}": {
      "put": {
        "operationId": "map_ledger_account_to_erp",
        "summary": "Map ledger account to ERP",
        "description": "Set one ledger account mapping. The external account must belong to this connection and match the mapped legal entity. Different mappings can be set concurrently. For the same mapping, the last accepted write wins. Repeating the same value leaves the mapping unchanged.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "ledger_account_id",
            "in": "path",
            "required": true,
            "description": "ID of the ledger account.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "lac_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The mapping was saved.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AccountMapping"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "glm_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "integration_type": "quickbooks",
                    "realm_id": "9341455734745729",
                    "internal_ledger_account_id": "lac_507f1f77bcf86cd799439011",
                    "external_ledger_account_id": "42",
                    "created_at": "2026-08-22T12:40:37.874Z",
                    "updated_at": "2026-08-31T03:49:29.365Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "external_id": {
                    "type": "string",
                    "description": "Copy external_id from this connection's external-accounts list.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "42"
                  }
                },
                "required": ["external_id"],
                "additionalProperties": false
              },
              "example": {
                "external_id": "42"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_erp_account_mapping",
        "summary": "Remove ERP account mapping",
        "description": "Remove one mapping from this connection. Posted journals and existing ERP records stay unchanged; future syncs require a valid mapping.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "ledger_account_id",
            "in": "path",
            "required": true,
            "description": "ID of the ledger account.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "lac_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged"
      }
    },
    "/v1/connections/{connection_id}/entity-mappings": {
      "get": {
        "operationId": "list_entity_mappings",
        "summary": "List entity mappings",
        "description": "List Entendre-to-ERP legal entity mappings for this connection and their validation status.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EntityMapping"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Mappings on this connection."
                    }
                  },
                  "required": ["count", "data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "lem_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "integration_type": "quickbooks",
                      "realm_id": "9341455734745729",
                      "internal_legal_entity_id": "le_507f1f77bcf86cd799439011",
                      "external_legal_entity_id": "1",
                      "created_at": "2026-08-22T12:40:37.874Z",
                      "updated_at": "2026-08-31T03:49:29.365Z"
                    }
                  ],
                  "count": 1,
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      }
    },
    "/v1/connections/{connection_id}/entity-mappings/{legal_entity_id}": {
      "put": {
        "operationId": "map_legal_entity_to_erp",
        "summary": "Map legal entity to ERP",
        "description": "Set one legal entity mapping. The external entity must belong to this connection, and dependent account mappings must remain valid. Different mappings can be set concurrently. For the same mapping, the last accepted write wins. Repeating the same value leaves the mapping unchanged.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "legal_entity_id",
            "in": "path",
            "required": true,
            "description": "ID of the legal entity.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "le_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The mapping was saved.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EntityMapping"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "lem_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "integration_type": "quickbooks",
                    "realm_id": "9341455734745729",
                    "internal_legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "external_legal_entity_id": "1",
                    "created_at": "2026-08-22T12:40:37.874Z",
                    "updated_at": "2026-08-31T03:49:29.365Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "external_id": {
                    "type": "string",
                    "description": "Copy external_id from this connection's external-entities list.",
                    "minLength": 1,
                    "maxLength": 500,
                    "example": "1"
                  }
                },
                "required": ["external_id"],
                "additionalProperties": false
              },
              "example": {
                "external_id": "1"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_erp_entity_mapping",
        "summary": "Remove ERP entity mapping",
        "description": "Remove one legal entity mapping when no dependent account mappings or active syncs require it.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "legal_entity_id",
            "in": "path",
            "required": true,
            "description": "ID of the legal entity.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "le_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "privileged"
      }
    },
    "/v1/connections/{connection_id}/imports": {
      "get": {
        "operationId": "list_erp_imports",
        "summary": "List accounting imports",
        "description": "Returns the connection's current import status. GL imports have no per-run history — only the single latest attempt is available, as a 0-or-1-item list. Returns an empty list before the first import.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The connection's current import status. An empty data array means nothing has been imported yet.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AccountingImport"
                      },
                      "maxItems": 1,
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "const": false,
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": "null",
                      "description": "Always `null`: the list is not paginated."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "glc_507f1f77bcf86cd799439011",
                      "status": "in_progress",
                      "progress": 40,
                      "message": "Importing chart of accounts...",
                      "error_message": null,
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:30Z",
                      "completed_at": null
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "import_from_erp",
        "summary": "Import accounting data",
        "description": "Import legal entities, chart of accounts and customer/supplier tags from a connected accounting system. The provider and connection determine which datasets are imported. There is no per-job polling: poll the plain GET on this same path for the connection’s current status, not a filtered URL for this one job.",
        "tags": ["GL Mapping"],
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "description": "ID of the connection.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "con_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted. Poll for the final outcome.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before you check the run status.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                },
                "example": 2
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "description": "Import job ID (`glc_…`)."
                        },
                        "integration_type": {
                          "type": "string",
                          "description": "General-ledger provider, such as `quickbooks`."
                        },
                        "realm_id": {
                          "type": ["string", "null"],
                          "description": "Company ID in the general ledger."
                        }
                      },
                      "required": ["job_id", "integration_type", "realm_id"]
                    },
                    "message": {
                      "type": "string",
                      "description": "Summary message."
                    }
                  },
                  "required": ["data", "message"]
                },
                "example": {
                  "data": {
                    "job_id": "glc_507f1f77bcf86cd799439011",
                    "integration_type": "quickbooks",
                    "realm_id": "9130350000000000"
                  },
                  "message": "QuickBooks import job queued"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Integrations",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Optional scope for the import.",
                "additionalProperties": false,
                "properties": {
                  "legal_entity_id": {
                    "type": "string",
                    "description": "The legal entity to import into. Required only when the connection is assigned to more than one legal entity; otherwise the single assigned entity is used.",
                    "example": "le_507f1f77bcf86cd799439011"
                  }
                }
              },
              "example": {
                "resource_types": ["legal_entities", "tags", "ledger_accounts"]
              }
            }
          }
        }
      }
    },
    "/v1/firm/requests": {
      "get": {
        "operationId": "list_requests",
        "summary": "List requests",
        "description": "Get requested items, recipients, progress and submitted resource links. Filter by request IDs or status. Requires a firm-owned API key with read:firms. Organization-owned keys cannot call this endpoint. Firm scope comes from the key, not the active client organization. Follow next_cursor while has_more is true, keeping all filters and sorting unchanged.",
        "tags": ["Request"],
        "parameters": [
          {
            "name": "request_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. Up to 100.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "string"
            },
            "example": ["frq_507f1f77bcf86cd799439011"]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Request lifecycle. Create a draft, then send it to begin client onboarding.",
            "schema": {
              "type": "string",
              "enum": ["pending", "partial", "completed", "expired", "cancelled"]
            }
          },
          {
            "name": "client_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. Up to 100.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include `total_count`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Sort field. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["created_at", "updated_at", "requested_at", "expires_at", "status"],
              "default": "created_at"
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "required": false,
            "description": "Sort direction. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirmRequest"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Present when include_count is true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "frq_507f1f77bcf86cd799439011",
                      "client_id": "fcl_000000000000000000000001",
                      "organization_id": "507f1f77bcf86cd799439013",
                      "status": "pending",
                      "integrations": [],
                      "email_sent": true,
                      "email_sent_at": "2026-08-31T12:00:00Z",
                      "expires_at": "2026-09-30T12:00:00Z",
                      "requested_at": "2026-08-31T12:00:00Z",
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_request",
        "summary": "Create request",
        "description": "Create a pending integration request and attempt email delivery immediately. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Firm scope comes from the key, not the active client organization. The `Idempotency-Key` header is required. Reuse the same key and request after a timeout. This sends email; only invoke for an explicit user request. Inspect email_sent to confirm delivery.",
        "tags": ["Request"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmRequest"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "frq_507f1f77bcf86cd799439011",
                    "client_id": "fcl_000000000000000000000001",
                    "organization_id": "507f1f77bcf86cd799439013",
                    "status": "pending",
                    "integrations": [],
                    "email_sent": true,
                    "email_sent_at": "2026-08-31T12:00:00Z",
                    "expires_at": "2026-09-30T12:00:00Z",
                    "requested_at": "2026-08-31T12:00:00Z",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "description": "Client that receives the request.",
                    "pattern": "^(?:fcl_)?[a-fA-F0-9]{24}$",
                    "example": "fcl_507f1f77bcf86cd799439011"
                  },
                  "integrations": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "wallet",
                            "exchange",
                            "bank",
                            "quickbooks",
                            "xero",
                            "netsuite",
                            "ramp",
                            "stripe-ar",
                            "gmail"
                          ],
                          "description": "Integration to request."
                        },
                        "legal_entity_id": {
                          "type": ["string", "null"],
                          "description": "Legal entity for this integration."
                        }
                      },
                      "required": ["type"],
                      "additionalProperties": false
                    },
                    "description": "Integrations to request."
                  }
                },
                "required": ["client_id", "integrations"],
                "additionalProperties": false
              },
              "example": {
                "client_id": "fcl_507f1f77bcf86cd799439011",
                "integrations": [
                  {
                    "type": "bank",
                    "legal_entity_id": "le_507f1f77bcf86cd799439012"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/firm/requests/{request_id}/resend": {
      "post": {
        "operationId": "resend_request",
        "summary": "Resend request",
        "description": "Trigger the existing request again. This keeps the same request and pending items. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Firm scope comes from the key, not the active client organization. The `Idempotency-Key` header is required. Reuse the same key and request after a timeout. This sends email; only invoke for an explicit user request. Inspect email_sent to confirm delivery.",
        "tags": ["Request"],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "description": "ID of the request.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "frq_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request was resent. Inspect email_sent for the delivery result.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmRequest"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "frq_507f1f77bcf86cd799439011",
                    "client_id": "fcl_000000000000000000000001",
                    "organization_id": "507f1f77bcf86cd799439013",
                    "status": "pending",
                    "integrations": [],
                    "email_sent": true,
                    "email_sent_at": "2026-08-31T12:00:00Z",
                    "expires_at": "2026-09-30T12:00:00Z",
                    "requested_at": "2026-08-31T12:00:00Z",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write"
      }
    },
    "/v1/firm/requests/{request_id}/cancel": {
      "post": {
        "operationId": "cancel_request",
        "summary": "Cancel request",
        "description": "Cancel the request and invalidate its client links. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Firm scope comes from the key, not the active client organization.",
        "tags": ["Request"],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "description": "ID of the request.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "frq_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID of the record."
                        },
                        "status": {
                          "type": "string",
                          "enum": ["cancelled"],
                          "description": "Always `cancelled`."
                        }
                      },
                      "required": ["id", "status"],
                      "additionalProperties": false,
                      "description": "The cancelled request."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "frq_507f1f77bcf86cd799439011",
                    "status": "cancelled"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write"
      }
    },
    "/v1/firm/clients": {
      "get": {
        "operationId": "list_clients",
        "summary": "List clients",
        "description": "Get client relationships, authorized organization IDs and onboarding state. Filter by client IDs, status or name. Requires a firm-owned API key with read:firms. Organization-owned keys cannot call this endpoint. Firm scope comes from the key, not the active client organization. Follow next_cursor while has_more is true, keeping all filters and sorting unchanged.",
        "tags": ["Client"],
        "parameters": [
          {
            "name": "client_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. Up to 100.",
            "style": "form",
            "explode": false,
            "schema": {
              "type": "string"
            },
            "example": ["fcl_507f1f77bcf86cd799439011"]
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Relationship state.",
            "schema": {
              "type": "string",
              "enum": ["draft", "active", "archived"]
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search of client organization name, contact name or contact email.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "organization_ids",
            "in": "query",
            "required": false,
            "description": "Comma-separated client organization IDs, up to 100. These differ from fcl_ relationship IDs.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include `total_count`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "include_archived",
            "in": "query",
            "required": false,
            "description": "Set false to exclude archived clients. Omission includes them.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Sort field. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["created_at", "updated_at", "status"],
              "default": "created_at"
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "required": false,
            "description": "Sort direction. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirmClient"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Present when include_count is true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "fcl_507f1f77bcf86cd799439011",
                      "organization_id": "507f1f77bcf86cd799439012",
                      "name": "Acme Finance",
                      "web_address": "acme-finance",
                      "timezone": "America/New_York",
                      "contact_name": "Alex Smith",
                      "contact_email": "alex@example.com",
                      "website": "https://example.com",
                      "logo_url": null,
                      "status": "draft",
                      "is_multi_entity": false,
                      "pending_actions": [],
                      "legal_entities_count": 1,
                      "agents_count": 0,
                      "integrations": [],
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "read"
      },
      "post": {
        "operationId": "create_client",
        "summary": "Create client",
        "description": "Create a draft client and its organization. Omit name and web_address to generate both values. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization. The `Idempotency-Key` header is required. Reuse the same key and request after a timeout.",
        "tags": ["Client"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmClient"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "fcl_507f1f77bcf86cd799439011",
                    "organization_id": "507f1f77bcf86cd799439012",
                    "name": "Acme Finance",
                    "web_address": "acme-finance",
                    "timezone": "America/New_York",
                    "contact_name": "Alex Smith",
                    "contact_email": "alex@example.com",
                    "website": "https://example.com",
                    "logo_url": null,
                    "status": "draft",
                    "is_multi_entity": false,
                    "pending_actions": [],
                    "legal_entities_count": 1,
                    "agents_count": 0,
                    "integrations": [],
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Client name. Supply this with web_address."
                  },
                  "web_address": {
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
                    "description": "Client Entendre subdomain slug. Supply this with name."
                  },
                  "contact_name": {
                    "type": ["string", "null"],
                    "description": "Client contact name."
                  },
                  "contact_email": {
                    "type": ["string", "null"],
                    "description": "Client contact email.",
                    "format": "email"
                  },
                  "website": {
                    "type": ["string", "null"],
                    "description": "Client public website.",
                    "format": "uri"
                  },
                  "timezone": {
                    "type": "string",
                    "description": "Client timezone."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Finance",
                "web_address": "acme-finance",
                "contact_name": "Alex Smith",
                "contact_email": "alex@example.com",
                "website": "https://example.com",
                "timezone": "America/New_York"
              }
            }
          }
        }
      }
    },
    "/v1/firm/clients/{client_id}": {
      "patch": {
        "operationId": "update_client",
        "summary": "Update client",
        "description": "Update client fields, or change the client status in a separate request. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Requires a firm administrator. Firm scope comes from the key, not the active client organization.",
        "tags": ["Client"],
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "ID of the client.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fcl_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmClient"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "fcl_507f1f77bcf86cd799439011",
                    "organization_id": "507f1f77bcf86cd799439012",
                    "name": "Acme Finance",
                    "web_address": "acme-finance",
                    "timezone": "America/New_York",
                    "contact_name": "Alex Smith",
                    "contact_email": "alex@example.com",
                    "website": "https://example.com",
                    "logo_url": null,
                    "status": "draft",
                    "is_multi_entity": false,
                    "pending_actions": [],
                    "legal_entities_count": 1,
                    "agents_count": 0,
                    "integrations": [],
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Draft client name."
                  },
                  "web_address": {
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
                    "description": "Draft client Entendre subdomain slug."
                  },
                  "contact_name": {
                    "type": ["string", "null"],
                    "description": "Client contact name."
                  },
                  "contact_email": {
                    "type": ["string", "null"],
                    "description": "Client contact email.",
                    "format": "email"
                  },
                  "website": {
                    "type": ["string", "null"],
                    "description": "Client public website.",
                    "format": "uri"
                  },
                  "is_multi_entity": {
                    "type": "boolean",
                    "description": "Whether the client uses multiple legal entities."
                  },
                  "pending_actions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "legal_entity_id": {
                          "type": ["string", "null"],
                          "description": "Legal entity for this action."
                        },
                        "integration_type": {
                          "type": "string",
                          "enum": [
                            "wallet",
                            "exchange",
                            "bank",
                            "quickbooks",
                            "xero",
                            "netsuite",
                            "ramp",
                            "stripe-ar",
                            "gmail"
                          ],
                          "description": "Integration for this action."
                        },
                        "action_type": {
                          "type": "string",
                          "enum": ["request", "connect"],
                          "description": "Action the client must complete."
                        }
                      },
                      "required": ["integration_type", "action_type"],
                      "additionalProperties": false
                    },
                    "description": "Client setup actions."
                  },
                  "status": {
                    "type": "string",
                    "enum": ["active", "archived"],
                    "description": "New client state. Send it without other fields. A firm API key can only activate a draft; archive and restore need the dashboard."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "contact_name": "Alex Smith",
                "contact_email": "alex@example.com"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "unlink_client",
        "summary": "Unlink client",
        "description": "Remove the firm relationship; preserve the client organization and its financial records. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Requires a firm administrator. Firm scope comes from the key, not the active client organization.",
        "tags": ["Client"],
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "ID of the client.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fcl_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged"
      }
    },
    "/v1/firm/members": {
      "get": {
        "operationId": "list_team_members",
        "summary": "List team members",
        "description": "List accepted firm members and their roles. Pending invitations are returned by the invitations endpoint. Requires a firm-owned API key with read:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Firm scope comes from the key, not the active client organization. Follow next_cursor while has_more is true, keeping all filters and sorting unchanged.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Membership state.",
            "schema": {
              "type": "string",
              "enum": ["accepted"]
            }
          },
          {
            "name": "member_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. Up to 100.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include `total_count`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "description": "Filter by firm role.",
            "schema": {
              "type": "string",
              "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"]
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Sort field. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["created_at", "updated_at", "email", "role", "status"],
              "default": "created_at"
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "required": false,
            "description": "Sort direction. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirmMember"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Present when include_count is true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "fmb_507f1f77bcf86cd799439011",
                      "user_id": "507f1f77bcf86cd799439012",
                      "email": "accountant@example.com",
                      "role": "FIRM_ACCOUNTANT",
                      "status": "accepted",
                      "invited_by": "507f1f77bcf86cd799439013",
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "read"
      }
    },
    "/v1/firm/members/{member_id}": {
      "patch": {
        "operationId": "update_team_member",
        "summary": "Update team member",
        "description": "Update a firm member role. The last administrator cannot be demoted. Unclassified historical client access returns 409 and requires reconciliation before retrying. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "member_id",
            "in": "path",
            "required": true,
            "description": "ID of the member.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fmb_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmMember"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "fmb_507f1f77bcf86cd799439011",
                    "user_id": "507f1f77bcf86cd799439012",
                    "email": "accountant@example.com",
                    "role": "FIRM_ACCOUNTANT",
                    "status": "accepted",
                    "invited_by": "507f1f77bcf86cd799439013",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"],
                    "description": "Firm role."
                  }
                },
                "required": ["role"],
                "additionalProperties": false
              },
              "example": {
                "role": "FIRM_ACCOUNTANT"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_team_member",
        "summary": "Remove team member",
        "description": "Remove firm membership and associated access without deleting the user. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization. Unclassified historical client access returns 409 and requires reconciliation before retrying.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "member_id",
            "in": "path",
            "required": true,
            "description": "ID of the member.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fmb_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged"
      }
    },
    "/v1/firm/invitations": {
      "get": {
        "operationId": "list_invitations",
        "summary": "List invitations",
        "description": "List pending or expired firm invitations. Accepted and revoked invitations are not returned. Requires a firm-owned API key with read:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Firm scope comes from the key, not the active client organization. Follow next_cursor while has_more is true, keeping all filters and sorting unchanged.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Invitation state.",
            "schema": {
              "type": "string",
              "enum": ["pending", "expired"]
            }
          },
          {
            "name": "invitation_ids",
            "in": "query",
            "required": false,
            "description": "IDs to return, separated by commas. Up to 100.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_count",
            "in": "query",
            "required": false,
            "description": "Set to `true` to include `total_count`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "description": "Filter by firm role.",
            "schema": {
              "type": "string",
              "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"]
            }
          },
          {
            "name": "sort_by",
            "in": "query",
            "required": false,
            "description": "Sort field. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["created_at", "updated_at", "email", "role", "status"],
              "default": "created_at"
            }
          },
          {
            "name": "sort_direction",
            "in": "query",
            "required": false,
            "description": "Sort direction. Keep unchanged across pages.",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FirmInvitation"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "total_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Present when include_count is true."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "fin_507f1f77bcf86cd799439011",
                      "member_id": "fmb_507f1f77bcf86cd799439011",
                      "user_id": null,
                      "email": "accountant@example.com",
                      "role": "FIRM_ACCOUNTANT",
                      "status": "pending",
                      "invited_by": "507f1f77bcf86cd799439013",
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:00:00Z",
                      "expires_at": "2026-09-14T12:00:00Z",
                      "email_sent": true
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged"
      },
      "post": {
        "operationId": "invite_team_member",
        "summary": "Invite team member",
        "description": "Invite a firm member. The invitation link expires after 14 days. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization. The `Idempotency-Key` header is required. Reuse the same key and request after a timeout. This sends email; only invoke for an explicit user request. Inspect email_sent to confirm delivery.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmInvitation"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "fin_507f1f77bcf86cd799439011",
                    "member_id": "fmb_507f1f77bcf86cd799439011",
                    "user_id": null,
                    "email": "accountant@example.com",
                    "role": "FIRM_ACCOUNTANT",
                    "status": "pending",
                    "invited_by": "507f1f77bcf86cd799439013",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "expires_at": "2026-09-14T12:00:00Z",
                    "email_sent": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Invitee email."
                  },
                  "role": {
                    "type": "string",
                    "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"],
                    "description": "Firm role."
                  }
                },
                "required": ["email", "role"],
                "additionalProperties": false
              },
              "example": {
                "email": "accountant@example.com",
                "role": "FIRM_ACCOUNTANT"
              }
            }
          }
        }
      }
    },
    "/v1/firm/invitations/{invitation_id}": {
      "delete": {
        "operationId": "revoke_invitation",
        "summary": "Revoke invitation",
        "description": "Delete a pending invitation. This does not remove a member who has already joined. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "invitation_id",
            "in": "path",
            "required": true,
            "description": "ID of the invitation.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fin_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted. The response has no body.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged"
      }
    },
    "/v1/firm/invitations/{invitation_id}/resend": {
      "post": {
        "operationId": "resend_invitation",
        "summary": "Resend invitation",
        "description": "Trigger an invitation link. The new link expires after 14 days and replaces the previous link. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization. The `Idempotency-Key` header is required. Reuse the same key and request after a timeout. This sends email; only invoke for an explicit user request. Inspect email_sent to confirm delivery.",
        "tags": ["Team"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Reuse this key with the same request to replay the completed result without sending another email.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            }
          },
          {
            "name": "invitation_id",
            "in": "path",
            "required": true,
            "description": "ID of the invitation.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "fin_507f1f77bcf86cd799439011"
          }
        ],
        "responses": {
          "200": {
            "description": "Invitation resent. `email_sent` shows whether the email was sent.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmInvitation"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "fin_507f1f77bcf86cd799439011",
                    "member_id": "fmb_507f1f77bcf86cd799439011",
                    "user_id": null,
                    "email": "accountant@example.com",
                    "role": "FIRM_ACCOUNTANT",
                    "status": "pending",
                    "invited_by": "507f1f77bcf86cd799439013",
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z",
                    "expires_at": "2026-09-14T12:00:00Z",
                    "email_sent": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "write"
      }
    },
    "/v1/firm/settings": {
      "get": {
        "operationId": "get_firm_settings",
        "summary": "Get firm settings",
        "description": "Get the firm name and Entendre subdomain slug. Requires a firm-owned API key with read:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Firm scope comes from the key, not the active client organization.",
        "tags": ["Settings"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmSettings"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "frm_507f1f77bcf86cd799439011",
                    "firm_name": "Example Accounting",
                    "web_address": "example-accounting",
                    "logo_url": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "read"
      },
      "patch": {
        "operationId": "update_firm_settings",
        "summary": "Update firm settings",
        "description": "Update the firm name or Entendre subdomain slug. Supply at least one field. Requires a firm-owned API key with write:firms. Organization-owned keys cannot call this endpoint. Client-restricted keys cannot access this operation. Requires a firm administrator. Firm scope comes from the key, not the active client organization.",
        "tags": ["Settings"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FirmSettings"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "frm_507f1f77bcf86cd799439011",
                    "firm_name": "Example Accounting",
                    "web_address": "example-accounting",
                    "logo_url": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The current state of the resource or an accounting rule prevents this operation. Read the resource again before you choose another action.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The resource state does not allow this operation.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Firms",
        "x-access-class": "privileged",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firm_name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Firm display name."
                  },
                  "web_address": {
                    "type": "string",
                    "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
                    "description": "Entendre subdomain slug."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "firm_name": "Example Accounting",
                "web_address": "example-accounting"
              }
            }
          }
        }
      }
    },
    "/v1/memory": {
      "get": {
        "tags": ["Memory"],
        "operationId": "listMemory",
        "summary": "List memory",
        "description": "List memory documents or operational rules. Select `kind=document` (default) or `kind=rule` in the query. Documents require memory permissions; rules require operational-rules permissions. Rule requests reject document-only fields, and document requests reject rule-only fields. Rules are organization-scoped and do not inherit firm documents.\n\nFor documents, supply an optional directory, limit, and cursor. Results use the existing document manifest envelope. For rules, optionally filter by domain (classification or cash_application). Returns the complete rule list as data with total_count, has_more=false, and next_cursor=null. Rule listings reject cursor, limit, and directory; counts_by_domain is included only without a domain filter.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "`document` (the default) for a memory document, or `rule` for an operational rule.",
            "schema": {
              "type": "string",
              "enum": ["document", "rule"],
              "default": "document"
            }
          },
          {
            "name": "directory",
            "in": "query",
            "schema": {
              "type": "string",
              "default": ""
            },
            "description": "Document only. Relative directory, such as `knowledge/`. Empty lists the tree root."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Document only. The `next_cursor` value from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            },
            "description": "Document only. Most documents to return in this page."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Rule only. Limits the lookup to one rule domain.",
            "schema": {
              "type": "string",
              "enum": ["classification", "cash_application"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File paths and metadata for the directory.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MemoryReadResult"
                    },
                    {
                      "type": "object",
                      "required": ["data", "has_more", "next_cursor"],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/OperationalRule"
                          },
                          "description": "The records."
                        },
                        "has_more": {
                          "type": "boolean",
                          "description": "`true` if more pages exist."
                        },
                        "next_cursor": {
                          "type": ["string", "null"],
                          "description": "Always `null`: the list is complete."
                        },
                        "counts_by_domain": {
                          "type": "object",
                          "properties": {
                            "classification": {
                              "type": "integer",
                              "description": "Classification rules."
                            },
                            "cash_application": {
                              "type": "integer",
                              "description": "Cash-application rules."
                            }
                          },
                          "description": "Total rules for each domain. Omitted when `domain` is set."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "documents": [
                    {
                      "path": "knowledge/vendors.md",
                      "layer": "org",
                      "frontmatter": null,
                      "suppressed": false
                    }
                  ],
                  "truncated": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid path, query or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Memory is temporarily unavailable. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_ERROR",
                    "message": "The memory service is temporarily unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-required-permissions": ["read:memory"],
        "x-product": "Agents",
        "x-access-class": "read"
      }
    },
    "/v1/memory/search": {
      "get": {
        "tags": ["Memory"],
        "operationId": "searchMemory",
        "summary": "Search memory",
        "description": "Search memory documents or operational rules. Select `kind=document` (default) or `kind=rule` in the query. Documents require memory permissions; rules require operational-rules permissions. Rule requests reject document-only fields, and document requests reject rule-only fields. Rules are organization-scoped and do not inherit firm documents.\n\nquery is required. Document search accepts root, scope, since, actor, and cursor and returns matching lines in the existing document envelope. Rule search optionally accepts domain and matches a case-insensitive substring across returned string fields, including IDs, names, and matcher text. It returns a complete data list, total_count of matches, has_more=false, and next_cursor=null. Rules reject document search filters and pagination.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "`document` (the default) for a memory document, or `rule` for an operational rule.",
            "schema": {
              "type": "string",
              "enum": ["document", "rule"],
              "default": "document"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500
            },
            "description": "Text to search for."
          },
          {
            "name": "root",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Document only. "
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["org", "firm"]
            },
            "description": "Document only. "
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Document only. "
          },
          {
            "name": "actor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Document only. "
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Document only. The `next_cursor` value from the previous page."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Rule only. Limits the lookup to one rule domain.",
            "schema": {
              "type": "string",
              "enum": ["classification", "cash_application"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching lines with their path and source layer.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MemorySearchResult"
                    },
                    {
                      "type": "object",
                      "required": ["data", "has_more", "next_cursor"],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/OperationalRule"
                          },
                          "description": "The records."
                        },
                        "has_more": {
                          "type": "boolean",
                          "description": "`true` if more pages exist."
                        },
                        "next_cursor": {
                          "type": ["string", "null"],
                          "description": "Always `null`: the list is complete."
                        },
                        "counts_by_domain": {
                          "type": "object",
                          "properties": {
                            "classification": {
                              "type": "integer",
                              "description": "Classification rules."
                            },
                            "cash_application": {
                              "type": "integer",
                              "description": "Cash-application rules."
                            }
                          },
                          "description": "Total rules for each domain. Omitted when `domain` is set."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "matches": [
                    {
                      "path": "knowledge/vendors.md",
                      "layer": "org",
                      "line": 1,
                      "text": "Treat approved staking rewards as revenue."
                    }
                  ],
                  "match_count": 1,
                  "truncated": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid path, query or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Memory is temporarily unavailable. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_ERROR",
                    "message": "The memory service is temporarily unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-required-permissions": ["read:memory"],
        "x-product": "Agents",
        "x-access-class": "read"
      }
    },
    "/v1/memory/file": {
      "get": {
        "tags": ["Memory"],
        "operationId": "readMemory",
        "summary": "Read memory",
        "description": "Read one memory document or operational rule. Select `kind=document` (default) or `kind=rule` in the query. Documents require memory permissions; rules require operational-rules permissions. Rule requests reject document-only fields, and document requests reject rule-only fields. Rules are organization-scoped and do not inherit firm documents.\n\nFor documents, path is required; the existing document response and optional cursor behavior are unchanged. For rules, rule_id is required and domain is optional. Returns {data: rule}, including its structured matcher fields; an unknown ID returns 404. Get rule IDs from List memory with `kind=rule`.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "`document` (the default) for a memory document, or `rule` for an operational rule.",
            "schema": {
              "type": "string",
              "enum": ["document", "rule"],
              "default": "document"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Document only, and required for documents. Relative file path, such as `knowledge/vendors.md`."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Document only. The `next_cursor` value from the previous page."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Rule only. Limits the lookup to one rule domain.",
            "schema": {
              "type": "string",
              "enum": ["classification", "cash_application"]
            }
          },
          {
            "name": "rule_id",
            "in": "query",
            "required": false,
            "description": "Rule only, and required for rules. Get it from List memory with `kind=rule`.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The resolved document.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MemoryReadResult"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OperationalRule"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "documents": [
                    {
                      "path": "knowledge/vendors.md",
                      "layer": "org",
                      "version": "version-example",
                      "content": "Treat approved staking rewards as revenue.",
                      "frontmatter": null,
                      "suppressed": false
                    }
                  ],
                  "truncated": false,
                  "next_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "Invalid path, query or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Memory is temporarily unavailable. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_ERROR",
                    "message": "The memory service is temporarily unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-required-permissions": ["read:memory"],
        "x-product": "Agents",
        "x-access-class": "read"
      },
      "put": {
        "tags": ["Memory"],
        "operationId": "writeMemory",
        "summary": "Write memory",
        "description": "Writes a memory document or an operational rule. Set `kind` to `document` (the default) or `rule`. Each body field is marked as document only or rule only.\n\nDocuments require the **write:memory** scope. Rules require the **write:operational-rules** scope and an API key with an owner.\n\nA document write replaces the full file. To replace a document, read it first and send its organization-layer version as `expected_version`. Document text is reference information; it does not change accounting controls.\n\nA saved rule applies to later classification and cash-application runs. It does not process transactions now; to classify selected transactions now, use Classify transactions. Rules apply only to your organization and do not inherit firm documents.\n\nReturns the saved document path, or the saved rule and its `outcome`. The document response does not include the new version; read the document again to get it.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "`document` (the default) for a memory document, or `rule` for an operational rule.",
            "schema": {
              "type": "string",
              "enum": ["document", "rule"],
              "default": "document"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Document only, and required for documents. Relative path of a Markdown or YAML file, such as `knowledge/vendors.md`. Use `profile.md`, `clients.yaml`, or a file in a folder. You cannot write JSON or JSONL files, or files in `refs/`, `journal/`, `artifacts/`, `timeline/`, `workstreams/`, `knowledge/facts/`, `knowledge/preferences/` or `knowledge/decisions/`. A skill must be `skills/{slug}/SKILL.md`. Firm documents allow only `policy/`, `knowledge/`, `skills/`, `profile.md` and `clients.yaml`."
          }
        ],
        "responses": {
          "200": {
            "description": "The organization memory file was saved.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MemoryWriteResult"
                    },
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "type": "object",
                          "required": ["outcome", "rule_id", "domain", "version", "summary", "rule"],
                          "properties": {
                            "outcome": {
                              "type": "string",
                              "enum": ["created", "already_exists", "replaced"],
                              "description": "`created` for a new rule, `already_exists` when the same rule exists (nothing changes), or `replaced` when a rule with the same match now has the new target."
                            },
                            "rule_id": {
                              "type": "string",
                              "description": "Rule ID."
                            },
                            "domain": {
                              "type": "string",
                              "enum": ["classification", "cash_application"],
                              "description": "Rule domain."
                            },
                            "version": {
                              "type": "string",
                              "description": "Version stamp of the rules file after the write."
                            },
                            "summary": {
                              "type": "string",
                              "description": "Human-readable outcome summary."
                            },
                            "rule": {
                              "$ref": "#/components/schemas/OperationalRule"
                            }
                          },
                          "description": "The result."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "success": true,
                  "path": "knowledge/vendors.md",
                  "layer": "org",
                  "rationale": "Record the approved treatment of staking rewards."
                }
              }
            }
          },
          "400": {
            "description": "Invalid path, query or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The supplied version does not match the organization file. Read it again before deciding to replace it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The supplied version does not match the organization file. Read it again before deciding to replace it.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Memory is temporarily unavailable. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_ERROR",
                    "message": "The memory service is temporarily unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "maxLength": 200000,
                    "description": "Document only, and required for documents. The full file body. A write replaces the file; it never merges."
                  },
                  "rationale": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Document only, and required for documents. Why you make this change. It is recorded with the document."
                  },
                  "expected_version": {
                    "type": ["string", "null"],
                    "description": "Document only, and required for documents. The `version` you read for this path, or `null` to create a new file. A mismatch returns HTTP 409."
                  },
                  "domain": {
                    "type": "string",
                    "enum": ["classification", "cash_application"],
                    "description": "Rule only. `classification` for transaction rules, or `cash_application` for deposit matching rules."
                  },
                  "description_contains": {
                    "type": "string",
                    "description": "Rule only. Classification rules: text that matches the memo or payee of a bank transaction. Saved and returned in lowercase. Matching ignores case."
                  },
                  "source_category": {
                    "type": "string",
                    "description": "Rule only. For classification rules: source-platform metadata category (Plaid personal-finance category, Ramp accounting category). Preferred for a class of transactions."
                  },
                  "merchant_name": {
                    "type": "string",
                    "description": "Rule only. For classification rules: merchant match for card spend (Ramp/Raincard)."
                  },
                  "blockchain_address": {
                    "type": "string",
                    "description": "Rule only. Classification rules: address that matches the from or to address. Saved and returned in lowercase. Matching ignores case."
                  },
                  "asset_type": {
                    "type": "string",
                    "description": "Rule only. For classification rules: asset match for crypto transactions (USDC, ETH, …)."
                  },
                  "direction": {
                    "type": "string",
                    "enum": ["DEPOSIT", "WITHDRAWAL", "ANY"],
                    "description": "Rule only. For classification rules: direction constraint. Defaults to ANY."
                  },
                  "category_ledger_account_id": {
                    "type": "string",
                    "description": "Rule only. Required for classification rules: the ledger account matching transactions are classified to. Get it from List ledger accounts."
                  },
                  "resolved_payee": {
                    "type": "string",
                    "description": "Rule only. For classification rules: clean payee name for display."
                  },
                  "default_tag_id": {
                    "type": "string",
                    "description": "Rule only. For classification rules: tag applied to matching transactions."
                  },
                  "title": {
                    "type": "string",
                    "description": "Rule only. Required for cash-application rules: short human-readable rule name."
                  },
                  "statement": {
                    "type": "string",
                    "description": "Rule only. Required for cash-application rules: natural-language statement of the rule."
                  },
                  "cash_application_action": {
                    "type": "string",
                    "enum": ["route_to_account", "require_human_review"],
                    "description": "Rule only. For cash-application rules: defaults to `route_to_account`."
                  },
                  "matcher": {
                    "type": "string",
                    "description": "Rule only. Required for cash-application rules: the exact phrase matched against invoice line descriptions / product names. Supply the SKU or product text verbatim."
                  },
                  "match_operator": {
                    "type": "string",
                    "enum": ["exact", "contains"],
                    "description": "Rule only. For cash-application rules: `contains` (default) fires when the line text contains the matcher anywhere; `exact` requires the normalized line label to equal it."
                  },
                  "ledger_account_id": {
                    "type": "string",
                    "description": "Rule only. Required for cash-application rules with `route_to_account`: target ledger account id. It is not inferred from the rule text."
                  },
                  "ledger_account_name": {
                    "type": "string",
                    "description": "Rule only. Required for cash-application rules with `route_to_account`: name matching `ledger_account_id`, for display and auditing."
                  }
                },
                "oneOf": [
                  {
                    "type": "object",
                    "required": ["content", "rationale", "expected_version"],
                    "properties": {
                      "content": {
                        "type": "string",
                        "maxLength": 200000,
                        "description": "The full file body. A write replaces the file; it never merges."
                      },
                      "rationale": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 2000,
                        "description": "Why you make this change. It is recorded with the document."
                      },
                      "expected_version": {
                        "type": ["string", "null"],
                        "description": "The `version` you read for this path, or `null` to create a new file. A mismatch returns HTTP 409."
                      }
                    },
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "required": ["domain"],
                    "properties": {
                      "domain": {
                        "type": "string",
                        "enum": ["classification", "cash_application"],
                        "description": "`classification` for transaction rules, or `cash_application` for deposit matching rules."
                      },
                      "description_contains": {
                        "type": "string",
                        "description": "Classification rules: text that matches the memo or payee of a bank transaction. Saved and returned in lowercase. Matching ignores case."
                      },
                      "source_category": {
                        "type": "string",
                        "description": "For classification rules: source-platform metadata category (Plaid personal-finance category, Ramp accounting category). Preferred for a class of transactions."
                      },
                      "merchant_name": {
                        "type": "string",
                        "description": "For classification rules: merchant match for card spend (Ramp/Raincard)."
                      },
                      "blockchain_address": {
                        "type": "string",
                        "description": "Classification rules: address that matches the from or to address. Saved and returned in lowercase. Matching ignores case."
                      },
                      "asset_type": {
                        "type": "string",
                        "description": "For classification rules: asset match for crypto transactions (USDC, ETH, …)."
                      },
                      "direction": {
                        "type": "string",
                        "enum": ["DEPOSIT", "WITHDRAWAL", "ANY"],
                        "description": "For classification rules: direction constraint. Defaults to ANY."
                      },
                      "category_ledger_account_id": {
                        "type": "string",
                        "description": "Required for classification rules: the ledger account matching transactions are classified to. Get it from List ledger accounts."
                      },
                      "resolved_payee": {
                        "type": "string",
                        "description": "For classification rules: clean payee name for display."
                      },
                      "default_tag_id": {
                        "type": "string",
                        "description": "For classification rules: tag applied to matching transactions."
                      },
                      "title": {
                        "type": "string",
                        "description": "Required for cash-application rules: short human-readable rule name."
                      },
                      "statement": {
                        "type": "string",
                        "description": "Required for cash-application rules: natural-language statement of the rule."
                      },
                      "cash_application_action": {
                        "type": "string",
                        "enum": ["route_to_account", "require_human_review"],
                        "description": "For cash-application rules: defaults to `route_to_account`."
                      },
                      "matcher": {
                        "type": "string",
                        "description": "Required for cash-application rules: the exact phrase matched against invoice line descriptions / product names. Supply the SKU or product text verbatim."
                      },
                      "match_operator": {
                        "type": "string",
                        "enum": ["exact", "contains"],
                        "description": "For cash-application rules: `contains` (default) fires when the line text contains the matcher anywhere; `exact` requires the normalized line label to equal it."
                      },
                      "ledger_account_id": {
                        "type": "string",
                        "description": "Required for cash-application rules with `route_to_account`: target ledger account id. It is not inferred from the rule text."
                      },
                      "ledger_account_name": {
                        "type": "string",
                        "description": "Required for cash-application rules with `route_to_account`: name matching `ledger_account_id`, for display and auditing."
                      }
                    },
                    "additionalProperties": false
                  }
                ]
              },
              "example": {
                "content": "Treat approved staking rewards as revenue.",
                "rationale": "Record the approved treatment of staking rewards.",
                "expected_version": null
              }
            }
          }
        },
        "x-required-permissions": ["write:memory"],
        "x-product": "Agents",
        "x-access-class": "write"
      },
      "delete": {
        "tags": ["Memory"],
        "operationId": "deleteMemory",
        "summary": "Delete memory",
        "description": "Move a memory document to trash, or delete an operational rule. Use `purge=true` to permanently delete an eligible document. Select `kind=document` (default) or `kind=rule` in the query. Documents require memory permissions; rules require operational-rules permissions. Rule requests reject document-only fields, and document requests reject rule-only fields. Rules are organization-scoped and do not inherit firm documents.\n\nDocuments require path and reason, with optional purge, and retain existing soft-delete behavior. Rules require rule_id, optionally domain, and the write:operational-rules scope plus an API-key owner. Get the ID from List memory with `kind=rule`. Rule deletion returns the existing rule deletion envelope; unknown IDs return 404. It affects subsequent runs and does not reverse prior classifications or journal entries.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "`document` (the default) for a memory document, or `rule` for an operational rule.",
            "schema": {
              "type": "string",
              "enum": ["document", "rule"],
              "default": "document"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Document only, and required for documents. Relative file path, such as `knowledge/vendors.md`."
          },
          {
            "name": "reason",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "Document only, and required for documents. Why the document is deleted."
          },
          {
            "name": "purge",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Document only. Delete permanently instead of moving to .trash/. Refused for policy/, journal/ and artifacts/."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Rule only. Limits the lookup to one rule domain.",
            "schema": {
              "type": "string",
              "enum": ["classification", "cash_application"]
            }
          },
          {
            "name": "rule_id",
            "in": "query",
            "required": false,
            "description": "Rule only, and required for rules. Get it from List memory with `kind=rule`.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The document was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MemoryDeleteResult"
                    },
                    {
                      "type": "object",
                      "required": ["data"],
                      "properties": {
                        "data": {
                          "type": "object",
                          "required": [
                            "deleted_rule_id",
                            "domain",
                            "deleted_rule_summary",
                            "version",
                            "remaining_count"
                          ],
                          "properties": {
                            "deleted_rule_id": {
                              "type": "string",
                              "description": "ID of the deleted rule."
                            },
                            "domain": {
                              "type": "string",
                              "enum": ["classification", "cash_application"],
                              "description": "Rule domain."
                            },
                            "deleted_rule_summary": {
                              "type": "string",
                              "description": "Human-readable summary of the deleted rule."
                            },
                            "version": {
                              "type": "string",
                              "description": "Version stamp of the rules file after the write."
                            },
                            "remaining_count": {
                              "type": "integer",
                              "description": "Rules remaining in the affected domain after the delete."
                            }
                          },
                          "description": "The result."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "deleted": true,
                  "path": "knowledge/vendors.md",
                  "purged": false,
                  "trash_path": ".trash/vendors-example.md"
                }
              }
            }
          },
          "400": {
            "description": "Invalid path, query or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The file to delete was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "The file to delete was not found.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Memory is temporarily unavailable. Retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemoryErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_ERROR",
                    "message": "The memory service is temporarily unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-required-permissions": ["write:memory"],
        "x-product": "Agents",
        "x-access-class": "write"
      }
    },
    "/v1/journal-entries/{journal_id}/unpost": {
      "post": {
        "operationId": "unpost_journal",
        "summary": "Unpost journal",
        "description": "Removes a posted journal from the ledger and detaches its transactions for correction or reclassification. The accounting period must be open. If the journal is synced, its ERP copy must be removed successfully first. Reversed journals cannot be unposted through this operation.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "journal_id",
            "in": "path",
            "required": true,
            "description": "ID of the journal.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "je_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The request succeeded.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/JournalEntry"
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "je_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "sequence_number": "JE-42",
                    "status": "unposted",
                    "originated_by": "user",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "posted_at": null,
                    "memo": "Record August opening balance",
                    "source_type": "MANUAL",
                    "sync_date": null,
                    "last_synced_at": null,
                    "last_unsynced_at": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "transaction_id": null,
                    "transaction_sequence_number": null,
                    "accounting_period_id": null,
                    "classification": null,
                    "tag_ids": [],
                    "reversal_chain": {
                      "previous_entry_id": null,
                      "next_entry_id": null
                    },
                    "period_auto_reassigned": false,
                    "intended_accounting_date": null,
                    "legal_entity_auto_assigned": false,
                    "lines": [
                      {
                        "id": "jel_507f1f77bcf86cd799439011",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "DEBIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      },
                      {
                        "id": "jel_507f1f77bcf86cd799439012",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "CREDIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      }
                    ],
                    "is_sync": false,
                    "latest_gl_sync_attempt": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The journal is not posted, or its accounting period is closed. No unpost is performed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The journal is not posted, or its accounting period is closed. No unpost is performed.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "502": {
            "description": "The ERP copy could not be removed. The journal remains posted; check its sync state before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "EXTERNAL_SERVICE_ERROR",
                    "message": "The ERP copy could not be removed. The journal remains posted; check its sync state before retrying.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/journal-entries/{journal_id}/post": {
      "post": {
        "operationId": "post_journal",
        "summary": "Post journal",
        "description": "Posts a draft or unposted journal to the ledger. Only draft and unposted journals can be posted; posted, reversed and errored journals are rejected. After an unpost-type correction, post the same journal again rather than creating a new transaction. Returns the posted journal.",
        "tags": ["Journals"],
        "parameters": [
          {
            "name": "journal_id",
            "in": "path",
            "required": true,
            "description": "ID of the journal.",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "je_507f1f77bcf86cd799439011"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "responses": {
          "200": {
            "description": "The journal was posted. If `read_back_failed` is `true`, the final status is unknown: read the journal before you retry.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/JournalEntry"
                    },
                    "read_back_failed": {
                      "type": "boolean",
                      "description": "Present and `true` only when the entry was saved but could not be read back. `data` then contains only `id`; use List journals to read the entry."
                    },
                    "warning": {
                      "type": "string",
                      "description": "Present only when `read_back_failed` is `true`."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "id": "je_507f1f77bcf86cd799439011",
                    "organization_id": "org_507f1f77bcf86cd799439011",
                    "sequence_number": "JE-42",
                    "status": "posted",
                    "originated_by": "user",
                    "accounting_date": "2026-08-31T12:00:00Z",
                    "posted_at": "2026-08-31T12:00:00Z",
                    "memo": "Record August opening balance",
                    "source_type": "MANUAL",
                    "sync_date": null,
                    "last_synced_at": null,
                    "last_unsynced_at": null,
                    "legal_entity_id": "le_507f1f77bcf86cd799439011",
                    "transaction_id": null,
                    "transaction_sequence_number": null,
                    "accounting_period_id": null,
                    "classification": null,
                    "tag_ids": [],
                    "reversal_chain": {
                      "previous_entry_id": null,
                      "next_entry_id": null
                    },
                    "period_auto_reassigned": false,
                    "intended_accounting_date": null,
                    "legal_entity_auto_assigned": false,
                    "lines": [
                      {
                        "id": "jel_507f1f77bcf86cd799439011",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439011",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "DEBIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      },
                      {
                        "id": "jel_507f1f77bcf86cd799439012",
                        "ledger_account_id": "lac_507f1f77bcf86cd799439012",
                        "legal_entity_id": "le_507f1f77bcf86cd799439011",
                        "credit_or_debit": "CREDIT",
                        "amount": "100.00",
                        "currency": "USD",
                        "memo": null,
                        "tag_ids": []
                      }
                    ],
                    "is_sync": false,
                    "latest_gl_sync_attempt": null,
                    "created_at": "2026-08-31T12:00:00Z",
                    "updated_at": "2026-08-31T12:00:00Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The journal is already posted, reversed or errored. Only draft and unposted journals can be posted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "The journal is already posted, reversed or errored. Only draft and unposted journals can be posted.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        },
        "x-product": "Core",
        "x-access-class": "write",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    },
    "/v1/journal-entries/syncs": {
      "post": {
        "operationId": "sync_journals",
        "summary": "Sync journals",
        "description": "Sends selected posted journals to the connected general ledger. Entendre groups the selection by legal entity and accounting period and queues one provider job per group, so one request can return several jobs. Read the run outcome with List journal sync jobs. Set `dry_run=true` to check which journals can be assigned to sync jobs without sending them. The preview returns HTTP 200 and lists assigned journals and missing configuration. A queued sync returns HTTP 202. Keep the same `journal_entry_ids` for the real request and send the returned `confirm_count`. This checks the distinct ID count, not the identity of those IDs or later changes to the journals. The preview does not guarantee provider acceptance; check the sync results after submission.",
        "tags": ["Journals"],
        "x-product": "Core",
        "x-access-class": "write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Unique key for this operation. Retry with the same key and request body after a timeout. Keys are retained for at least 24 hours.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "example-operation-2026-08-31-001"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "journal_entry_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "Journal ID (`je_…`).",
                      "example": "je_507f1f77bcf86cd799439011"
                    },
                    "minItems": 1,
                    "maxItems": 5000,
                    "description": "Journals to sync. Duplicates are accepted and collapsed. The destination is resolved per journal from its legal entity; there is no connection parameter."
                  },
                  "confirm_count": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Safety check. When supplied it must equal the number of distinct IDs in journal_entry_ids, otherwise the request is rejected before any journal is sent."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "description": "Preview only. Runs the same validation and routing and reports which journals would be queued, without sending anything. Returns 200, not 202."
                  },
                  "agent_instance_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Attributes the sync to an agent instead of the API-key user. Must be sent together with agent_name."
                  },
                  "agent_name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Display name of the initiating agent. Must be sent together with agent_instance_id."
                  }
                },
                "required": ["journal_entry_ids"],
                "additionalProperties": false
              },
              "example": {
                "journal_entry_ids": ["je_507f1f77bcf86cd799439011"],
                "confirm_count": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dry-run preview. Nothing was sent to the provider.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "dry_run": {
                          "type": "boolean",
                          "const": true,
                          "description": "`true` for a preview."
                        },
                        "confirm_count": {
                          "type": "integer",
                          "description": "Value to send as confirm_count on the real call."
                        },
                        "summary": {
                          "type": "object",
                          "properties": {
                            "requested": {
                              "type": "integer",
                              "description": "Distinct journals submitted."
                            },
                            "journal_entries": {
                              "type": "integer",
                              "description": "Journals that would be queued."
                            },
                            "failed": {
                              "type": "integer",
                              "description": "Journals that would not be routed."
                            }
                          },
                          "required": ["requested", "journal_entries", "failed"],
                          "additionalProperties": false,
                          "description": "Counts for the preview."
                        },
                        "eligible": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Journals that would be queued."
                        },
                        "failed": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Journal ID."
                              },
                              "reason": {
                                "type": "string",
                                "description": "Why the journal would not be synced."
                              }
                            },
                            "required": ["id", "reason"],
                            "additionalProperties": false
                          },
                          "description": "Journals that no provider job would cover, each with the reason. A journal lands here when its legal entity has no general-ledger configuration."
                        }
                      },
                      "required": ["dry_run", "confirm_count", "summary", "eligible", "failed"],
                      "additionalProperties": false,
                      "description": "The sync result."
                    }
                  },
                  "required": ["data"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "dry_run": true,
                    "confirm_count": 1,
                    "summary": {
                      "requested": 1,
                      "journal_entries": 1,
                      "failed": 0
                    },
                    "eligible": ["je_507f1f77bcf86cd799439011"],
                    "failed": []
                  }
                }
              }
            }
          },
          "202": {
            "description": "Accepted. One job per (legal entity, accounting period) group in the selection. An empty jobs array means no journal was routed to a provider.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "jobs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "job_id": {
                                "type": ["string", "null"],
                                "description": "Job ID. Check the result with List journal sync jobs."
                              },
                              "display_name": {
                                "type": ["string", "null"],
                                "description": "Human-readable job label."
                              }
                            },
                            "required": ["job_id", "display_name"],
                            "additionalProperties": false
                          },
                          "description": "Queued provider jobs."
                        },
                        "jobs_count": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Number of queued jobs."
                        }
                      },
                      "required": ["jobs", "jobs_count"],
                      "additionalProperties": false,
                      "description": "The sync result."
                    },
                    "message": {
                      "type": "string",
                      "description": "Summary message."
                    }
                  },
                  "required": ["data", "message"],
                  "additionalProperties": false
                },
                "example": {
                  "data": {
                    "jobs": [
                      {
                        "job_id": "apid:jeid",
                        "display_name": "Syncing March 2026 to QuickBooks"
                      }
                    ],
                    "jobs_count": 1
                  },
                  "message": "1 sync job(s) queued; subscribe to SSE on each job_id for progress"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "One or more journals do not exist, or your organization cannot access them. No journal is sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "One or more journal IDs are absent or not visible to the authenticated tenant.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "409": {
            "description": "The destination general ledger refused the credentials. Reconnect the connection, then retry. No journal is sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "CONFLICT",
                    "message": "QuickBooks authorization expired. Reconnect the general-ledger connection and retry.",
                    "details": {
                      "auth_error": true
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "list_journal_sync_jobs",
        "summary": "List journal sync jobs",
        "description": "Lists general-ledger sync runs for the organization, newest first. One row per run: an accounting period pushed to one provider, with its synced and failed counts. Only completed runs are returned by default; include_all adds failed, canceled and hanged runs, include_in_progress adds running ones. Always read status_counts before reporting sync health, because it tallies the runs the default hides.",
        "tags": ["Journals"],
        "x-product": "Core",
        "x-access-class": "read",
        "parameters": [
          {
            "name": "integration_type",
            "in": "query",
            "required": false,
            "description": "Restrict to one destination provider.",
            "schema": {
              "type": "string",
              "enum": ["quickbooks", "xero", "netsuite", "dualentry", "campfire"]
            }
          },
          {
            "name": "include_all",
            "in": "query",
            "required": false,
            "description": "Include failed, canceled and hanged runs alongside completed ones.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "include_in_progress",
            "in": "query",
            "required": false,
            "description": "Include runs that have started but not finished.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `next_cursor` value from the previous page. Keep the other filters unchanged.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sync runs in the authenticated organization. An empty data array means no run matches; status_counts still reports what the filters hid.",
            "headers": {
              "X-Request-Id": {
                "description": "Support correlation ID.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/JournalSync"
                      },
                      "description": "The records."
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Whether another page is available."
                    },
                    "next_cursor": {
                      "type": ["string", "null"],
                      "description": "Cursor for the next page, or `null` on the last page."
                    },
                    "status_counts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      },
                      "description": "Run counts by status. Statuses with no runs are omitted."
                    }
                  },
                  "required": ["data", "has_more", "next_cursor", "status_counts"],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "sh_507f1f77bcf86cd799439011",
                      "organization_id": "org_507f1f77bcf86cd799439011",
                      "accounting_period_id": "ap_507f1f77bcf86cd799439011",
                      "created_by": "usr_507f1f77bcf86cd799439011",
                      "integration_type": "quickbooks",
                      "job_status": "completed",
                      "synced_count": 12,
                      "failed_count": 0,
                      "total_count": 12,
                      "completed_at": "2026-08-31T12:01:00Z",
                      "error_message": null,
                      "created_at": "2026-08-31T12:00:00Z",
                      "updated_at": "2026-08-31T12:01:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "status_counts": {
                    "COMPLETED": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. `error.fields` lists the fields to correct. Nothing was changed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Invalid path, query or request body.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Authentication is required.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "403": {
            "description": "The API key does not have the required scope or is not associated with a user, or the action needs a review in the dashboard.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "Insufficient access to organization",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or your organization cannot access it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RESOURCE_NOT_FOUND",
                    "message": "Resource not found",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. If the response has a `Retry-After` header, wait that many seconds before you retry. Otherwise, read `error.message`.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Retry after 30s.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. A write can still have taken effect; check the resource before you retry. Give the `request_id` to support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Internal server error",
                    "request_id": "req_example"
                  }
                }
              }
            }
          },
          "503": {
            "description": "A service that this operation needs is unavailable. If the response has a `Retry-After` header, wait that many seconds. Check for earlier accepted work before you send the request again.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "SERVICE_UNAVAILABLE",
                    "message": "Service unavailable.",
                    "request_id": "req_example"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your organization API key. Some operations also need a key that is associated with a user; their pages say so."
      }
    },
    "schemas": {
      "Integration": {
        "type": "object",
        "description": "The connection status of one provider.",
        "properties": {
          "provider": {
            "type": "string",
            "description": "Provider key.",
            "example": "stripe"
          },
          "category": {
            "type": "string",
            "enum": ["accounting", "cards", "banking", "payroll", "receivables", "custody", "communication"]
          },
          "connected": {
            "type": "boolean",
            "description": "True when at least one connection is `active`."
          },
          "count": {
            "type": "integer",
            "description": "Number of connection records for this provider."
          },
          "unavailable": {
            "type": "boolean",
            "description": "Present and true when the status could not be read. The state is unknown, not disconnected."
          },
          "connections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IntegrationConnection"
            }
          }
        },
        "required": ["provider", "category", "connected", "count", "connections"],
        "additionalProperties": false
      },
      "IntegrationConnection": {
        "type": "object",
        "description": "One stored connection of a provider.",
        "properties": {
          "id": {
            "type": ["string", "null"],
            "description": "Connection ID, or null when the provider has no connection ID."
          },
          "status": {
            "type": "string",
            "enum": ["active", "expired", "error", "disconnected", "inactive", "pending"],
            "description": "Status of the stored connection record. It is not a live check of the provider."
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "description": "Legal entity of the connection, or null for providers that connect at organization level."
          },
          "legal_entity_name": {
            "type": ["string", "null"]
          },
          "external_id": {
            "type": ["string", "null"],
            "description": "Provider-side ID. For a GL provider, the realm or tenant ID."
          },
          "external_name": {
            "type": ["string", "null"]
          },
          "connected_at": {
            "type": ["string", "null"],
            "format": "date-time"
          },
          "last_activity_at": {
            "type": ["string", "null"],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "status",
          "legal_entity_id",
          "legal_entity_name",
          "external_id",
          "external_name",
          "connected_at",
          "last_activity_at"
        ],
        "additionalProperties": false
      },
      "AccountMapping": {
        "type": "object",
        "required": ["id", "integration_type", "realm_id", "external_ledger_account_id"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Mapping ID (`glm_…`).",
            "example": "glm_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": ["string", "null"],
            "example": "org_abc123",
            "description": "Organization ID (`org_…`)."
          },
          "integration_type": {
            "type": "string",
            "enum": ["quickbooks", "xero", "netsuite", "dualentry", "campfire"],
            "description": "General-ledger provider."
          },
          "realm_id": {
            "type": "string",
            "description": "Company ID in the general ledger."
          },
          "internal_ledger_account_id": {
            "type": ["string", "null"],
            "description": "Entendre ledger account ID (`lac_…`). Match it with the `id` of a ledger account."
          },
          "external_ledger_account_id": {
            "type": "string",
            "description": "Account ID in the general ledger, as returned by List external accounts."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the mapping was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the mapping was last updated (ISO 8601)."
          }
        }
      },
      "AccountingPeriod": {
        "type": "object",
        "required": ["id", "organization_id", "name", "start_date", "end_date", "status"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["ap_123def"],
            "description": "Accounting period ID (`ap_…`)."
          },
          "organization_id": {
            "type": "string",
            "description": "Prefixed organization ID.",
            "examples": ["org_abc123"]
          },
          "name": {
            "type": "string",
            "description": "Period name, such as `September 2026`."
          },
          "start_date": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the period, in the organization timezone."
          },
          "end_date": {
            "type": "string",
            "format": "date-time",
            "description": "End of the period, in the organization timezone."
          },
          "status": {
            "type": "string",
            "enum": ["open", "soft_closed", "closed"],
            "description": "Accounting period status."
          },
          "legal_entity_id": {
            "type": "string",
            "description": "Legal entity this period belongs to.",
            "example": "le_507f1f77bcf86cd799439011"
          },
          "closed_on_date": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the period was closed."
          },
          "closed_by": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "User who closed the period."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp.",
            "example": "2025-01-01T00:00:00.000Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp.",
            "example": "2025-01-01T00:00:00.000Z"
          },
          "start_date_utc": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "UTC start date of the period, used by the start-date filter. It can differ from `start_date`, which uses the organization timezone."
          }
        }
      },
      "Accrual": {
        "type": "object",
        "description": "A vendor accrual row. `vendor_id` is `vnd_<id>`, `journal_entry_id` is `je_<id>`.",
        "properties": {
          "id": {
            "type": ["string", "null"],
            "description": "Accrual ID (`acc_…`)."
          },
          "vendor_id": {
            "type": ["string", "null"],
            "description": "Vendor ID (`vnd_…`)."
          },
          "vendor_name": {
            "type": ["string", "null"],
            "description": "Vendor name."
          },
          "amount": {
            "type": ["string", "null"],
            "description": "Decimal string."
          },
          "period": {
            "type": ["string", "null"],
            "description": "Month, in `YYYY-MM` format."
          },
          "status": {
            "type": ["string", "null"],
            "description": "Accrual status."
          },
          "journal_entry_id": {
            "type": ["string", "null"],
            "description": "Journal ID (`je_…`)."
          },
          "journal_sequence_number": {
            "type": ["string", "null"],
            "description": "Journal sequence number, such as `JE-42`."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the accrual was created (ISO 8601)."
          }
        },
        "required": ["id", "vendor_id", "vendor_name", "amount", "period", "status", "journal_entry_id"]
      },
      "AccrualCreateResult": {
        "type": "object",
        "description": "Per-entry create result. `created`/`failed` partition the requested accruals.",
        "properties": {
          "accruals_created": {
            "type": "integer",
            "description": "Number of accruals created."
          },
          "accruals_failed": {
            "type": "integer",
            "description": "Number of accruals that failed."
          },
          "total_amount": {
            "type": "string",
            "description": "Total amount of the created accruals (decimal string)."
          },
          "reversal_date": {
            "type": ["string", "null"],
            "description": "Date on which the accruals reverse, or `null`."
          },
          "created": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "accrual_id": {
                  "type": "string",
                  "description": "Accrual ID (`acc_…`)."
                },
                "journal_entry_id": {
                  "type": ["string", "null"],
                  "description": "Journal ID (`je_…`)."
                },
                "journal_sequence_number": {
                  "type": ["string", "null"],
                  "description": "Journal sequence number, such as `JE-42`."
                },
                "vendor_id": {
                  "type": ["string", "null"],
                  "description": "Vendor ID (`vnd_…`)."
                },
                "vendor_name": {
                  "type": "string",
                  "description": "Vendor name."
                },
                "amount": {
                  "type": "number",
                  "description": "Accrual amount."
                },
                "period": {
                  "type": "string",
                  "description": "Accrual month, in `YYYY-MM` format."
                },
                "reversal_date": {
                  "type": ["string", "null"],
                  "description": "Reversal date, or `null`."
                },
                "confidence": {
                  "type": ["integer", "null"],
                  "description": "Confidence that you sent with the accrual."
                }
              }
            },
            "description": "Accruals that were created."
          },
          "failed": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "vendor_id": {
                  "type": ["string", "null"],
                  "description": "Vendor ID (`vnd_…`)."
                },
                "vendor_name": {
                  "type": "string",
                  "description": "Vendor name."
                },
                "amount": {
                  "type": "number",
                  "description": "Accrual amount."
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "duplicate",
                    "vendor_account_not_mapped",
                    "multiple_legal_entities",
                    "accounting_period_closed",
                    "unknown"
                  ],
                  "description": "Why the accrual failed."
                },
                "message": {
                  "type": "string",
                  "description": "Explanation of the failure."
                },
                "details": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Additional details about the failure."
                }
              }
            },
            "description": "Accruals that were not created."
          }
        }
      },
      "AccrualReversal": {
        "type": "object",
        "properties": {
          "accrual_id": {
            "type": "string",
            "description": "Accrual ID (`acc_…`).",
            "example": "acc_507f1f77bcf86cd799439011"
          },
          "journal_entry_id": {
            "type": "string",
            "description": "Journal ID (`je_…`).",
            "example": "je_507f1f77bcf86cd799439011"
          },
          "reversal_journal_entry_id": {
            "type": "string",
            "description": "Journal ID (`je_…`).",
            "example": "je_507f1f77bcf86cd799439011"
          },
          "reversal_date": {
            "type": "string",
            "description": "ISO calendar date.",
            "format": "date",
            "example": "2026-08-31"
          },
          "status": {
            "type": "string",
            "description": "The reversing journal is recorded.",
            "enum": ["reversed"]
          }
        },
        "required": ["accrual_id", "journal_entry_id", "reversal_journal_entry_id", "reversal_date", "status"],
        "additionalProperties": false
      },
      "ActionHint": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "description": "Stable operation name."
          },
          "available": {
            "type": "boolean",
            "description": "Whether the action is currently available."
          },
          "reason": {
            "type": ["string", "null"],
            "description": "Why unavailable, or null."
          },
          "url": {
            "type": ["string", "null"],
            "description": "Authorized relative API or dashboard URL, or null."
          }
        },
        "required": ["action", "available", "reason", "url"],
        "additionalProperties": false
      },
      "Address": {
        "type": "object",
        "required": ["line1", "city", "country"],
        "properties": {
          "line1": {
            "type": "string",
            "description": "Street address."
          },
          "line2": {
            "type": ["string", "null"],
            "description": "Apartment, suite or unit."
          },
          "city": {
            "type": "string",
            "description": "City."
          },
          "state": {
            "type": ["string", "null"],
            "description": "State/province. Optional for countries without states."
          },
          "country": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code (such as `US`, `GB`)."
          },
          "zipcode": {
            "type": "string",
            "description": "Postal code."
          }
        }
      },
      "Agent": {
        "type": "object",
        "required": ["id", "name", "agent_type", "status", "is_active", "organization_id", "created_at"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["agt_abc123"],
            "description": "Agent ID (`agt_…`)."
          },
          "name": {
            "type": "string",
            "description": "Agent name."
          },
          "agent_type": {
            "type": ["string", "null"],
            "readOnly": true,
            "description": "Agent type."
          },
          "status": {
            "type": "string",
            "enum": ["active", "paused", "archived"],
            "description": "Lifecycle status. Paused and archived agents cannot start new runs."
          },
          "is_active": {
            "type": "boolean",
            "deprecated": true,
            "description": "`true` when the agent is active. `status` gives the exact state.",
            "readOnly": true
          },
          "description": {
            "type": ["string", "null"],
            "description": "What the agent does."
          },
          "cron_expressions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Raw 5-field cron expressions. For display, use the human-readable `schedule` instead of these raw strings."
          },
          "schedule": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Readable schedule for each `cron_expressions` item, in the organization timezone. Empty when the agent has no schedule."
          },
          "triggers": {
            "type": "array",
            "description": "Triggers that start the agent. Only triggers with `is_active: true` start it.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Trigger ID."
                },
                "trigger_type": {
                  "type": "string",
                  "description": "`schedule` for a cron trigger, or a `*_webhook` type for an event trigger."
                },
                "is_active": {
                  "type": "boolean",
                  "description": "`true` when the trigger starts the agent."
                },
                "cron_expressions": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Cron expressions for a `schedule` trigger; empty for webhook triggers."
                },
                "event_types": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Event names a webhook trigger listens for; empty for a `schedule` trigger."
                },
                "last_triggered_at": {
                  "type": ["string", "null"],
                  "format": "date-time",
                  "description": "Last time the trigger started the agent."
                },
                "created_at": {
                  "type": ["string", "null"],
                  "format": "date-time",
                  "description": "Time the agent was created (ISO 8601)."
                },
                "updated_at": {
                  "type": ["string", "null"],
                  "format": "date-time",
                  "description": "Time the agent was last updated (ISO 8601)."
                }
              }
            }
          },
          "emails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Email notification recipients."
          },
          "slack_channel_id": {
            "type": ["string", "null"],
            "description": "Slack channel ID for notifications."
          },
          "organization_id": {
            "type": "string",
            "description": "Organization ID (`org_…`)."
          },
          "last_run_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time of the latest run."
          },
          "last_error_message": {
            "type": ["string", "null"],
            "description": "Error message from the most recent failed run."
          },
          "latest_run": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AgentRun"
              },
              {
                "type": "null"
              }
            ],
            "description": "The latest run, or `null`."
          },
          "last_agent_run_status": {
            "type": ["string", "null"],
            "description": "Latest run status. Only included in list responses."
          },
          "owner_user_id": {
            "type": ["string", "null"],
            "description": "Prefixed `usr_` id of the assignable owner (defaults to the creator), or null."
          },
          "reviewer_user_id": {
            "type": ["string", "null"],
            "description": "Prefixed `usr_` id of the assignable run reviewer, or null."
          },
          "month_end_review_behavior": {
            "type": ["string", "null"],
            "enum": ["auto_complete", "carry_over", null],
            "description": "What happens at month end to a run that waits for review. `auto_complete` closes it. `carry_over` keeps it pending."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the agent was created (ISO 8601)."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the agent was last updated (ISO 8601)."
          },
          "created_by": {
            "type": ["string", "null"],
            "description": "ID of the user who created the agent."
          },
          "arguments": {
            "type": "object",
            "description": "Agent settings. `legalEntityIds` lists the legal entities (`le_…`). `sourceIds` lists the source IDs without a type prefix."
          },
          "slack_team_id": {
            "type": ["string", "null"],
            "description": "Slack workspace ID of the agent, or `null`."
          },
          "enabled_mcp_connection_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "MCP connections that the agent can use."
          }
        }
      },
      "AgentRun": {
        "type": "object",
        "required": ["id", "agent_id", "status", "created_at", "status_url"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["run_xyz789"],
            "description": "Run ID (`run_…`)."
          },
          "status": {
            "type": "string",
            "enum": ["in_progress", "pending_review", "success", "error", "skipped"],
            "description": "Run status. `pending_review` waits for a review. `skipped` means that the agent was paused or archived before the run started. A cancelled run currently ends as `error`."
          },
          "success_data": {
            "type": ["string", "null"],
            "description": "Result data on success."
          },
          "error_data": {
            "type": ["string", "null"],
            "description": "Error details on failure."
          },
          "error_message": {
            "type": ["string", "null"],
            "description": "Human-readable error message."
          },
          "reviewed_by": {
            "type": ["string", "null"],
            "description": "The user who approved the run."
          },
          "reviewed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time of the review decision, or `null` before a decision."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the run was created (ISO 8601)."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the run was last updated (ISO 8601)."
          },
          "agent_id": {
            "type": "string",
            "description": "ID of the agent that owns the run.",
            "example": "agt_507f1f77bcf86cd799439011"
          },
          "review": {
            "$ref": "#/components/schemas/Review"
          },
          "result_links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResourceLink"
            },
            "description": "Records that the run created or changed."
          },
          "status_url": {
            "type": "string",
            "readOnly": true,
            "description": "URL that returns this run through List agent runs.",
            "example": "/v1/agents/agt_507f1f77bcf86cd799439011/runs?run_ids=run_xyz789"
          }
        }
      },
      "Asset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Prefixed asset ID (`ast_`).",
            "examples": ["ast_abc123"]
          },
          "asset_type": {
            "type": "string",
            "examples": ["ETH"],
            "description": "Asset symbol, such as `ETH`."
          },
          "quantity": {
            "type": "string",
            "description": "Decimal string.",
            "examples": ["10.5"]
          },
          "remaining_quantity": {
            "type": "string",
            "examples": ["8.25"],
            "description": "Quantity still held (decimal string)."
          },
          "cost_basis": {
            "type": "string",
            "examples": ["15750.00"],
            "description": "Cost basis of the acquisition. Uses the marked basis when one exists."
          },
          "currency": {
            "type": "string",
            "examples": ["USD"],
            "description": "Currency of the cost basis."
          },
          "date_received": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Acquisition date (ISO 8601)."
          },
          "chain": {
            "type": ["string", "null"],
            "description": "Blockchain network, such as `eth`."
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "examples": ["le_456def"],
            "description": "Legal entity ID (`le_…`)."
          },
          "ledger_account_id": {
            "type": ["string", "null"],
            "examples": ["lac_789ghi"],
            "description": "Ledger account ID (`lac_…`)."
          },
          "transaction_id": {
            "type": ["string", "null"],
            "examples": ["txn_012jkl"],
            "description": "Transaction that created the asset record (`txn_…`)."
          },
          "source_id": {
            "type": ["string", "null"],
            "examples": ["src_507f1f77bcf86cd799439011"],
            "description": "Source ID for this asset."
          },
          "is_manual": {
            "type": "boolean",
            "description": "`true` for a manual opening asset."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the asset record was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the asset record was last updated (ISO 8601)."
          }
        },
        "required": ["id", "asset_type", "quantity", "remaining_quantity", "cost_basis", "currency"]
      },
      "BalanceSheet": {
        "type": "object",
        "properties": {
          "ledger_accounts": {
            "type": "array",
            "description": "The ledger accounts on the report, in the same shape as List ledger accounts.",
            "items": {
              "$ref": "#/components/schemas/LedgerAccount"
            }
          },
          "balances": {
            "type": "object",
            "description": "Keyed by prefixed ledger account ID → period name → balance row.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/components/schemas/FinancialReportRow"
              }
            }
          },
          "data_quality": {
            "type": "object",
            "description": "Checks for periods with negative total assets and periods where assets do not equal liabilities plus equity.",
            "properties": {
              "negative_asset_periods": {
                "type": "array",
                "description": "Periods whose total assets are negative. Each entry is `{ period, total }` (decimal-string total).",
                "items": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string",
                      "description": "Accounting period name."
                    },
                    "total": {
                      "type": "string",
                      "description": "Total assets (decimal string)."
                    }
                  }
                }
              },
              "unbalanced_periods": {
                "type": "array",
                "description": "Periods where assets do not equal liabilities plus equity.",
                "items": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string",
                      "description": "Accounting period name."
                    },
                    "assets": {
                      "type": "string",
                      "description": "Total assets (decimal string)."
                    },
                    "liabilities_plus_equity": {
                      "type": "string",
                      "description": "Total liabilities plus equity (decimal string)."
                    },
                    "difference": {
                      "type": "string",
                      "description": "Assets minus liabilities plus equity (decimal string)."
                    }
                  }
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Human-readable `[WARNING]` strings for any raised condition (negative-asset, or does-not-foot)."
              }
            }
          }
        },
        "required": ["ledger_accounts", "balances"]
      },
      "CashPreview": {
        "type": "object",
        "required": ["deposit", "derived_customer", "suggestions", "candidate_pool_size", "truncated"],
        "additionalProperties": false,
        "properties": {
          "deposit": {
            "type": "object",
            "required": ["id", "amount", "memo", "txn_date"],
            "properties": {
              "id": {
                "type": ["string", "null"],
                "description": "Deposit transaction (`txn_…`)."
              },
              "amount": {
                "type": "string",
                "description": "Deposit amount (decimal string)."
              },
              "memo": {
                "type": ["string", "null"],
                "description": "Deposit memo."
              },
              "txn_date": {
                "type": ["string", "null"],
                "format": "date-time",
                "description": "Deposit date (ISO 8601)."
              }
            },
            "description": "The deposit to apply."
          },
          "derived_customer": {
            "type": ["object", "null"],
            "properties": {
              "id": {
                "type": "string",
                "description": "Customer ID at the provider."
              },
              "name": {
                "type": "string",
                "description": "Customer name."
              },
              "source": {
                "type": ["string", "null"],
                "enum": ["hint", "memo_match", null],
                "description": "How the customer was found: `hint` from your request or `memo_match` from the deposit memo."
              }
            },
            "description": "Customer that the preview identified, or `null`."
          },
          "suggestions": {
            "type": "array",
            "description": "Candidates in match-priority order. Empty when no match is found.",
            "items": {
              "type": "object",
              "required": ["match_type", "confidence", "total_amount", "delta", "allocations"],
              "properties": {
                "match_type": {
                  "type": "string",
                  "enum": ["exact", "multi_invoice", "tolerance"],
                  "description": "`exact` for one invoice with the same amount, `multi_invoice` for several invoices, `tolerance` for an amount within the tolerance."
                },
                "confidence": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Confidence of the suggestion, from 0 to 1."
                },
                "total_amount": {
                  "type": "string",
                  "description": "Total of the suggested invoices (decimal string)."
                },
                "delta": {
                  "type": "string",
                  "description": "Difference between the deposit and the suggested invoice total."
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/V1CashApplicationAllocation"
                  },
                  "description": "Invoice allocations to send when you create the cash application."
                }
              }
            }
          },
          "candidate_pool_size": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of invoices that the preview checked."
          },
          "truncated": {
            "type": "boolean",
            "description": "The candidate pool reached its search cap; more invoices may exist."
          }
        }
      },
      "Classification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Classification ID (`cls_…`).",
            "example": "cls_507f1f77bcf86cd799439011"
          },
          "status": {
            "type": "string",
            "description": "Job status.",
            "enum": ["queued", "in_progress", "succeeded", "partially_succeeded", "failed", "cancelled"]
          },
          "status_url": {
            "type": "string",
            "description": "URL to check this classification job."
          },
          "total_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Transactions selected for this job."
          },
          "processed_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Transactions processed across all result pages."
          },
          "totals": {
            "type": "object",
            "properties": {
              "input": {
                "type": "integer",
                "minimum": 0,
                "description": "Selected transactions."
              },
              "classified": {
                "type": "integer",
                "minimum": 0,
                "description": "Classified transactions, including those posted."
              },
              "pending_review": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions that need review."
              },
              "unclassified": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions without a classification."
              },
              "auto_posted": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions with posted journal entries."
              },
              "posting_failed": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions whose journal posting failed, across all pages."
              },
              "posting_skipped": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions whose journal posting was skipped, across all pages."
              }
            },
            "required": [
              "input",
              "classified",
              "pending_review",
              "unclassified",
              "auto_posted",
              "posting_failed",
              "posting_skipped"
            ],
            "additionalProperties": false,
            "description": "Counts across all result pages."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClassificationLine"
            },
            "description": "Result items on this page."
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether more result rows are available."
          },
          "next_cursor": {
            "type": ["string", "null"],
            "description": "Cursor for the next result page."
          },
          "error": {
            "type": ["object", "null"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Failure code."
              },
              "message": {
                "type": "string",
                "description": "Failure description."
              }
            },
            "required": ["code", "message"],
            "additionalProperties": false,
            "description": "Why the job failed, or `null`."
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601 UTC timestamp.",
            "format": "date-time",
            "example": "2026-08-31T12:00:00Z"
          },
          "completed_at": {
            "type": ["string", "null"],
            "description": "Time the job finished (ISO 8601)."
          },
          "review_url": {
            "type": ["string", "null"],
            "format": "uri",
            "description": "Dashboard link for reviewing the selected transactions, when available. This is not an additional approval step before automatic posting."
          }
        },
        "required": [
          "id",
          "status",
          "status_url",
          "total_count",
          "processed_count",
          "totals",
          "items",
          "has_more",
          "next_cursor",
          "error",
          "created_at",
          "completed_at",
          "review_url"
        ],
        "additionalProperties": false
      },
      "ClassificationLine": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "description": "Transaction ID."
          },
          "status": {
            "type": "string",
            "enum": ["classified", "pending_review", "unclassified", "failed"],
            "description": "Classification outcome. `posting_status` gives the accounting result."
          },
          "classification": {
            "type": ["string", "null"],
            "description": "Assigned transaction classification."
          },
          "category_ledger_account_id": {
            "type": ["string", "null"],
            "description": "Assigned category ledger account."
          },
          "payment_account_id": {
            "type": ["string", "null"],
            "description": "Payment ledger account."
          },
          "confidence": {
            "type": ["number", "null"],
            "description": "Confidence of the classification."
          },
          "reason": {
            "type": "string",
            "description": "Reason for the classification or required review."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Fields needed to complete classification."
          },
          "posting_status": {
            "type": "string",
            "enum": ["not_posted", "posted", "replayed", "skipped", "failed"],
            "description": "A classification can succeed even when posting is skipped or fails."
          },
          "journal_entry_id": {
            "type": ["string", "null"],
            "description": "Created or previously posted journal entry."
          },
          "posting_message": {
            "type": ["string", "null"],
            "description": "Posting failure or skip reason."
          }
        },
        "required": [
          "transaction_id",
          "status",
          "classification",
          "category_ledger_account_id",
          "payment_account_id",
          "confidence",
          "reason",
          "missing_fields",
          "posting_status",
          "journal_entry_id",
          "posting_message"
        ],
        "additionalProperties": false
      },
      "CloseReadiness": {
        "type": "object",
        "properties": {
          "accounting_period": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Record ID."
              },
              "status": {
                "type": "string",
                "enum": ["Open", "Closed", "Soft Closed"],
                "description": "Period status."
              },
              "start_date": {
                "type": "string",
                "format": "date",
                "description": "Period start date."
              },
              "end_date": {
                "type": "string",
                "format": "date",
                "description": "Period end date."
              },
              "legal_entity_id": {
                "type": "string",
                "description": "Legal entity ID (`le_…`)."
              }
            },
            "description": "The accounting period that was checked."
          },
          "preconditions": {
            "type": "object",
            "properties": {
              "can_close": {
                "type": "boolean",
                "description": "`true` when nothing blocks the close."
              },
              "blocking_reasons": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "What blocks the close."
              }
            },
            "description": "Whether the period can be closed."
          },
          "pending_transactions": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer",
                "description": "Number of pending transactions."
              },
              "sum_credit_usd": {
                "type": "number",
                "description": "Total of pending credits, in USD."
              },
              "sum_debit_usd": {
                "type": "number",
                "description": "Total of pending debits, in USD."
              },
              "preview": {
                "type": "array",
                "description": "Some of the pending transactions."
              }
            },
            "description": "Transactions in the period that are not posted."
          },
          "draft_journal_entries": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer",
                "description": "Number of draft journals."
              },
              "preview": {
                "type": "array",
                "description": "Some of the draft journals."
              }
            },
            "description": "Draft journals in the period."
          },
          "recommendation": {
            "type": "string",
            "enum": ["safe_to_close", "hold"],
            "description": "`safe_to_close` or `hold`."
          }
        },
        "additionalProperties": false
      },
      "ClosingPosition": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "Asset symbol, such as `ETH`."
          },
          "quantity": {
            "type": "string",
            "description": "Quantity held (decimal string)."
          },
          "cost_basis": {
            "type": "string",
            "description": "Cost basis (decimal string)."
          },
          "weighted_average_cost": {
            "type": "string",
            "description": "Weighted average cost per unit (decimal string)."
          },
          "current_price": {
            "type": "string",
            "description": "Price per unit on the reporting date (decimal string)."
          },
          "market_value": {
            "type": "string",
            "description": "Quantity times price (decimal string)."
          },
          "unrealized_gain": {
            "type": "string",
            "description": "Market value minus cost basis (decimal string)."
          },
          "date": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Reporting date of the position."
          }
        }
      },
      "Connection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Connection ID (`con_…`).",
            "example": "con_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": "string",
            "description": "Organization ID (`org_…`).",
            "example": "org_507f1f77bcf86cd799439011"
          },
          "provider": {
            "type": "string",
            "description": "Provider identifier.",
            "example": "quickbooks"
          },
          "auth_method": {
            "type": "string",
            "description": "Setup method.",
            "enum": ["oauth", "api_key"]
          },
          "name": {
            "type": "string",
            "description": "Connection display name."
          },
          "status": {
            "type": "string",
            "description": "Connection status.",
            "enum": ["pending_setup", "active", "expired", "disconnecting", "disconnected", "failed"]
          },
          "external_account_id": {
            "type": ["string", "null"],
            "description": "Account ID at the provider."
          },
          "legal_entity_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Legal entity ID (`le_…`).",
              "example": "le_507f1f77bcf86cd799439011"
            },
            "description": "Legal entities of the connection (`le_…`)."
          },
          "source_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Source ID (`src_…`).",
              "example": "src_507f1f77bcf86cd799439011"
            },
            "description": "Sources created from the connection."
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Supported action."
            },
            "description": "Actions that the connection supports."
          },
          "authorization_attempt": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Authorization attempt ID (`auth_…`).",
                "example": "auth_507f1f77bcf86cd799439011"
              },
              "status": {
                "type": "string",
                "description": "Status of the setup attempt.",
                "enum": ["pending", "succeeded", "expired", "failed"]
              },
              "setup_url": {
                "type": ["string", "null"],
                "description": "Setup URL for the user. It expires and is not a credential."
              },
              "expires_at": {
                "type": ["string", "null"],
                "description": "Expiry time (ISO 8601)."
              },
              "error": {
                "type": ["string", "null"],
                "description": "Why the setup failed."
              }
            },
            "required": ["id", "status"],
            "additionalProperties": false,
            "description": "The latest setup attempt."
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601 UTC timestamp.",
            "format": "date-time",
            "example": "2026-08-31T12:00:00Z"
          },
          "guidance": {
            "$ref": "#/components/schemas/Guidance"
          },
          "revocation_error": {
            "type": ["string", "null"],
            "description": "Why the provider did not revoke access. A disabled connection in Entendre does not prove that the provider revoked access."
          },
          "retained_resources": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Resource types retained after disconnect."
            },
            "description": "Resource types that stay after a disconnect."
          },
          "etag": {
            "type": "string",
            "readOnly": true,
            "pattern": "^\"[^\"\\r\\n]+\"$",
            "description": "Strong version of this resource. Send this value, including its quotes, in If-Match when updating it.",
            "examples": ["\"v_example\""]
          },
          "cleanup": {
            "type": "object",
            "description": "Present after bank disconnect. Counts rows removed by this call. Zero is valid for empty or already-cleaned connections.",
            "properties": {
              "accounts_deleted": {
                "type": "integer",
                "minimum": 0,
                "description": "Bank accounts deleted."
              },
              "transactions_deleted": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions deleted."
              }
            },
            "required": ["accounts_deleted", "transactions_deleted"]
          },
          "importable_resources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "General-ledger connections only: the resource types that the connection can import."
          }
        },
        "required": [
          "id",
          "organization_id",
          "provider",
          "auth_method",
          "name",
          "status",
          "external_account_id",
          "legal_entity_ids",
          "source_ids",
          "capabilities",
          "created_at",
          "guidance",
          "etag"
        ],
        "additionalProperties": false
      },
      "DecimalValue": {
        "type": "object",
        "description": "Decimal amount as an object. `value` is a decimal string, never a float.",
        "required": ["value"],
        "properties": {
          "value": {
            "type": "string",
            "examples": ["1250.00"],
            "description": "Decimal string."
          }
        }
      },
      "Disposition": {
        "type": "object",
        "properties": {
          "asset_type": {
            "type": "string",
            "description": "Asset symbol, such as `ETH`."
          },
          "asset_record": {
            "type": "string",
            "description": "Asset record ID."
          },
          "date_received": {
            "type": "string",
            "format": "date-time",
            "description": "Acquisition date (ISO 8601)."
          },
          "quantity": {
            "type": "string",
            "description": "Quantity acquired (decimal string)."
          },
          "remaining_quantity": {
            "type": "string",
            "description": "Quantity still held (decimal string)."
          },
          "cost_basis": {
            "type": "string",
            "description": "Cost basis per unit (decimal string)."
          },
          "disposals": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sale_date": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Date of the disposal (ISO 8601)."
                },
                "quantity_sold": {
                  "type": "string",
                  "description": "Quantity disposed (decimal string)."
                },
                "sale_price": {
                  "type": "string",
                  "description": "Proceeds per unit (decimal string)."
                }
              },
              "required": ["sale_date", "quantity_sold", "sale_price"]
            },
            "description": "Disposals of this lot."
          },
          "currency": {
            "type": "string",
            "description": "Currency of the proceeds and cost basis.",
            "example": "USD"
          }
        }
      },
      "EntityMapping": {
        "type": "object",
        "required": ["id", "integration_type", "realm_id", "external_legal_entity_id"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Mapping ID (`lem_…`).",
            "example": "lem_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": ["string", "null"],
            "example": "org_abc123",
            "description": "Organization ID (`org_…`)."
          },
          "integration_type": {
            "type": "string",
            "enum": ["quickbooks", "xero", "netsuite", "dualentry", "campfire"],
            "description": "General-ledger provider."
          },
          "realm_id": {
            "type": "string",
            "description": "Company ID in the general ledger."
          },
          "internal_legal_entity_id": {
            "type": ["string", "null"],
            "description": "Prefixed legal entity (`le_…`)."
          },
          "external_legal_entity_id": {
            "type": "string",
            "description": "Entity or subsidiary ID in the general ledger, as returned by List external entities."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the mapping was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the mapping was last updated (ISO 8601)."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "request_id"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code."
              },
              "message": {
                "type": "string",
                "description": "Technical description for developers."
              },
              "fields": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Present only on VALIDATION_ERROR. Maps failing field paths to reason strings."
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "Optional redacted diagnostic details. Request validation uses fields or field_errors."
              },
              "suggested_action": {
                "type": "string",
                "description": "A suggested next step."
              },
              "documentation_url": {
                "type": "string",
                "format": "uri",
                "description": "Link to documentation about this error."
              },
              "request_id": {
                "type": "string",
                "description": "Unique request ID for support escalation."
              }
            },
            "description": "Error details."
          }
        }
      },
      "FinancialInsight": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "revenue",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": ["total", "currency", "time_series"],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "total": {
                    "type": "string",
                    "description": "Total income over the window (decimal string)."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "time_series": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/V1FinancialInsightSeriesPoint"
                    },
                    "description": "Values for each bucket."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "profit",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": ["total_revenue", "total_expenses", "total_profit", "currency", "time_series"],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "total_revenue": {
                    "type": "string",
                    "description": "Total income (decimal string)."
                  },
                  "total_expenses": {
                    "type": "string",
                    "description": "Total expenses (decimal string)."
                  },
                  "total_profit": {
                    "type": "string",
                    "description": "total_revenue minus total_expenses (decimal string)."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "time_series": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["period_start", "period_end", "revenue", "expenses", "profit"],
                      "properties": {
                        "period_start": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Start of the bucket."
                        },
                        "period_end": {
                          "type": "string",
                          "format": "date-time",
                          "description": "End of the bucket."
                        },
                        "revenue": {
                          "type": "string",
                          "description": "Revenue in the bucket (decimal string)."
                        },
                        "expenses": {
                          "type": "string",
                          "description": "Expenses in the bucket (decimal string)."
                        },
                        "profit": {
                          "type": "string",
                          "description": "Revenue minus expenses in the bucket (decimal string)."
                        }
                      }
                    },
                    "description": "Values for each bucket."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "expenses",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": ["total", "by_category", "currency", "time_series"],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "total": {
                    "type": "string",
                    "description": "Total expenses over the window (decimal string)."
                  },
                  "by_category": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/V1FinancialInsightCategoryAmount"
                    },
                    "description": "Totals by category."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "time_series": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["period_start", "period_end", "total", "categories"],
                      "properties": {
                        "period_start": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Start of the bucket."
                        },
                        "period_end": {
                          "type": "string",
                          "format": "date-time",
                          "description": "End of the bucket."
                        },
                        "total": {
                          "type": "string",
                          "description": "Total in the bucket (decimal string)."
                        },
                        "categories": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/V1FinancialInsightCategoryAmount"
                          },
                          "description": "Totals by category in the bucket."
                        }
                      }
                    },
                    "description": "Values for each bucket."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "spending",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": ["total", "by_source_type", "by_classification", "currency", "time_series"],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "total": {
                    "type": "string",
                    "description": "Total spending over the window (decimal string)."
                  },
                  "by_source_type": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/V1FinancialInsightSpendingEntry"
                    },
                    "description": "Totals by source type."
                  },
                  "by_classification": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/V1FinancialInsightSpendingEntry"
                    },
                    "description": "Totals by transaction type."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "time_series": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["period_start", "period_end", "total", "by_source_type", "by_classification"],
                      "properties": {
                        "period_start": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Start of the bucket."
                        },
                        "period_end": {
                          "type": "string",
                          "format": "date-time",
                          "description": "End of the bucket."
                        },
                        "total": {
                          "type": "string",
                          "description": "Total in the bucket (decimal string)."
                        },
                        "by_source_type": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/V1FinancialInsightSpendingEntry"
                          },
                          "description": "Totals by source type in the bucket."
                        },
                        "by_classification": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/V1FinancialInsightSpendingEntry"
                          },
                          "description": "Totals by transaction type in the bucket."
                        }
                      }
                    },
                    "description": "Values for each bucket."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "burn_rate",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": [
                  "average_monthly_burn",
                  "cash_flow_positive",
                  "total_expenses",
                  "total_income",
                  "months_analyzed",
                  "currency",
                  "trend",
                  "no_data"
                ],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "average_monthly_burn": {
                    "type": "string",
                    "description": "Net burn (total outflows minus inflows) divided by months in the window (decimal string). Negative when the organization is net cash-flow positive."
                  },
                  "cash_flow_positive": {
                    "type": "boolean",
                    "description": "True when net burn is <= 0 (inflows cover outflows over the window)."
                  },
                  "total_expenses": {
                    "type": "string",
                    "description": "Total expenses (outflows) over the window (decimal string)."
                  },
                  "total_income": {
                    "type": "string",
                    "description": "Total income (inflows) over the window (decimal string)."
                  },
                  "months_analyzed": {
                    "type": "integer",
                    "description": "Number of whole months in the window. Normally >= 1; 0 only when basis=ledger and the window overlaps no accounting period (see no_data)."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "trend": {
                    "type": "array",
                    "description": "Per-bucket net burn (outflows minus inflows) as single-amount series points.",
                    "items": {
                      "$ref": "#/components/schemas/V1FinancialInsightSeriesPoint"
                    }
                  },
                  "no_data": {
                    "type": "boolean",
                    "description": "`true` when `basis=ledger` and the window has no accounting periods."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "runway",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": [
                  "months_remaining",
                  "cash_flow_positive",
                  "current_cash",
                  "average_monthly_burn",
                  "currency",
                  "no_data"
                ],
                "properties": {
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  },
                  "months_remaining": {
                    "type": ["string", "null"],
                    "description": "`current_cash` divided by `average_monthly_burn` (decimal string). `null` when the organization is cash-flow positive."
                  },
                  "cash_flow_positive": {
                    "type": "boolean",
                    "description": "True when net burn (outflows minus inflows) is <= 0. When true, months_remaining is null and runway is not applicable."
                  },
                  "current_cash": {
                    "type": "string",
                    "description": "Current cash position (decimal string)."
                  },
                  "average_monthly_burn": {
                    "type": "string",
                    "description": "Net burn (total outflows minus inflows) divided by months in the window (decimal string). Negative when the organization is net cash-flow positive."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "no_data": {
                    "type": "boolean",
                    "description": "`true` when `basis=ledger` and the window has no accounting periods, so runway cannot be calculated."
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "metric": {
                "type": "string",
                "const": "cash_flow",
                "description": "Metric name."
              },
              "value": {
                "type": ["string", "null"],
                "description": "Summary decimal value; null for unavailable or inapplicable metrics."
              },
              "unit": {
                "type": "string",
                "description": "Unit of the value, such as `USD` or `months`."
              },
              "formula": {
                "type": "string",
                "description": "Formula and effective calculation basis."
              },
              "reason": {
                "type": ["string", "null"],
                "description": "Why a value is unavailable or qualified."
              },
              "details": {
                "type": "object",
                "required": ["net_flow", "total_inflows", "total_outflows", "currency", "time_series"],
                "properties": {
                  "net_flow": {
                    "type": "string",
                    "description": "total_inflows minus total_outflows (decimal string)."
                  },
                  "total_inflows": {
                    "type": "string",
                    "description": "Total income over the window (decimal string)."
                  },
                  "total_outflows": {
                    "type": "string",
                    "description": "Total expenses over the window (decimal string)."
                  },
                  "currency": {
                    "type": "string",
                    "example": "USD",
                    "description": "Currency of the amounts."
                  },
                  "time_series": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["period_start", "period_end", "inflows", "outflows", "net", "cumulative_net"],
                      "properties": {
                        "period_start": {
                          "type": "string",
                          "format": "date-time",
                          "description": "Start of the bucket."
                        },
                        "period_end": {
                          "type": "string",
                          "format": "date-time",
                          "description": "End of the bucket."
                        },
                        "inflows": {
                          "type": "string",
                          "description": "Money in during the bucket (decimal string)."
                        },
                        "outflows": {
                          "type": "string",
                          "description": "Money out during the bucket (decimal string)."
                        },
                        "net": {
                          "type": "string",
                          "description": "Inflows minus outflows in the bucket (decimal string)."
                        },
                        "cumulative_net": {
                          "type": "string",
                          "description": "Net flow from the window start through this bucket (decimal string)."
                        }
                      }
                    },
                    "description": "Values for each bucket."
                  },
                  "data_quality": {
                    "$ref": "#/components/schemas/TransactionInsightDataQuality"
                  }
                },
                "description": "Values of the metric."
              },
              "meta": {
                "$ref": "#/components/schemas/V1FinancialInsightMeta"
              }
            },
            "required": ["metric", "value", "unit", "formula", "reason", "details", "meta"],
            "additionalProperties": false
          }
        ]
      },
      "FinancialReportRow": {
        "type": "object",
        "description": "Balance data for one ledger account in one accounting period. Decimals are `{ value }` objects.",
        "required": ["credit_debit", "tag_balance"],
        "properties": {
          "credit_debit": {
            "type": "object",
            "required": [
              "opening_balance",
              "closing_balance",
              "current_balance",
              "debits",
              "credits",
              "accounting_period_start_date_utc",
              "legal_entity_ids"
            ],
            "properties": {
              "opening_balance": {
                "$ref": "#/components/schemas/DecimalValue"
              },
              "closing_balance": {
                "$ref": "#/components/schemas/DecimalValue"
              },
              "current_balance": {
                "$ref": "#/components/schemas/DecimalValue"
              },
              "debits": {
                "$ref": "#/components/schemas/DecimalValue"
              },
              "credits": {
                "$ref": "#/components/schemas/DecimalValue"
              },
              "accounting_period_start_date_utc": {
                "type": ["string", "null"],
                "format": "date-time",
                "description": "UTC start date of the accounting period this row belongs to."
              },
              "legal_entity_ids": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Prefixed legal entity IDs (`le_`) whose balances contribute to this row."
              }
            },
            "description": "Debit and credit figures for the row."
          },
          "tag_balance": {
            "$ref": "#/components/schemas/DecimalValue",
            "description": "Balance attributable to the requested tag. `0` unless the report was filtered with `tag_id`."
          }
        }
      },
      "FirmClient": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Firm client ID.",
            "pattern": "^(?:fcl_)?[a-fA-F0-9]{24}$",
            "example": "fcl_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": "string",
            "description": "Organization created for this client."
          },
          "name": {
            "type": "string",
            "description": "Client organization name."
          },
          "web_address": {
            "type": "string",
            "description": "Client Entendre subdomain slug."
          },
          "timezone": {
            "type": "string",
            "description": "Client timezone."
          },
          "contact_name": {
            "type": "string",
            "description": "Client contact name."
          },
          "contact_email": {
            "type": "string",
            "description": "Client contact email."
          },
          "website": {
            "type": ["string", "null"],
            "description": "Client public website.",
            "format": "uri"
          },
          "logo_url": {
            "type": ["string", "null"],
            "description": "Client logo URL.",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": ["draft", "active", "archived"],
            "description": "Client relationship state."
          },
          "is_multi_entity": {
            "type": "boolean",
            "description": "Whether the client uses multiple legal entities."
          },
          "pending_actions": {
            "type": "array",
            "description": "Setup actions that remain for the client.",
            "items": {
              "type": "object",
              "properties": {
                "legal_entity_id": {
                  "type": ["string", "null"],
                  "description": "Legal entity for this action."
                },
                "integration_type": {
                  "type": "string",
                  "enum": [
                    "wallet",
                    "exchange",
                    "bank",
                    "quickbooks",
                    "xero",
                    "netsuite",
                    "ramp",
                    "stripe-ar",
                    "gmail"
                  ],
                  "description": "Integration for this action."
                },
                "action_type": {
                  "type": "string",
                  "enum": ["request", "connect"],
                  "description": "Action the client must complete."
                }
              },
              "required": ["legal_entity_id", "integration_type", "action_type"],
              "additionalProperties": false
            }
          },
          "legal_entities_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Client legal entity count."
          },
          "agents_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Client agent count."
          },
          "integrations": {
            "type": "array",
            "description": "Available client integrations.",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "description": "Integration type."
                },
                "connected": {
                  "type": "boolean",
                  "description": "Whether the integration is connected."
                },
                "legal_entity_id": {
                  "type": ["string", "null"],
                  "description": "Connected legal entity."
                }
              },
              "required": ["type", "connected", "legal_entity_id"],
              "additionalProperties": false
            }
          },
          "default_legal_entity_id": {
            "type": "string",
            "description": "Default legal entity created with a new client.",
            "readOnly": true
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the client was created.",
            "format": "date-time"
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Time the client was last updated.",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "organization_id",
          "name",
          "web_address",
          "timezone",
          "contact_name",
          "contact_email",
          "website",
          "logo_url",
          "status",
          "is_multi_entity",
          "pending_actions",
          "legal_entities_count",
          "agents_count",
          "integrations",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "FirmInvitation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Firm invitation ID.",
            "pattern": "^(?:fin_)?[a-fA-F0-9]{24}$",
            "example": "fin_507f1f77bcf86cd799439011"
          },
          "user_id": {
            "type": ["string", "null"],
            "description": "User ID after the invitation is accepted."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Member email."
          },
          "role": {
            "type": "string",
            "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"],
            "description": "Firm role."
          },
          "status": {
            "type": "string",
            "enum": ["pending", "expired"],
            "description": "Invitation state."
          },
          "invited_by": {
            "type": ["string", "null"],
            "description": "User who sent the invitation."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the invitation was created.",
            "format": "date-time"
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Time the invitation was last updated.",
            "format": "date-time"
          },
          "member_id": {
            "type": "string",
            "description": "Member ID used to update the pending role.",
            "pattern": "^(?:fmb_)?[a-fA-F0-9]{24}$",
            "example": "fmb_507f1f77bcf86cd799439011"
          },
          "expires_at": {
            "type": ["string", "null"],
            "description": "Time the current invitation link expires.",
            "format": "date-time"
          },
          "email_sent": {
            "type": "boolean",
            "description": "Whether the invitation email was sent."
          }
        },
        "required": [
          "id",
          "member_id",
          "user_id",
          "email",
          "role",
          "status",
          "invited_by",
          "created_at",
          "updated_at",
          "expires_at"
        ],
        "additionalProperties": false
      },
      "FirmMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Firm member ID.",
            "pattern": "^(?:fmb_)?[a-fA-F0-9]{24}$",
            "example": "fmb_507f1f77bcf86cd799439011"
          },
          "user_id": {
            "type": ["string", "null"],
            "description": "User ID after the invitation is accepted."
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Member email."
          },
          "role": {
            "type": "string",
            "enum": ["FIRM_ADMIN", "FIRM_ACCOUNTANT"],
            "description": "Firm role."
          },
          "status": {
            "type": "string",
            "enum": ["pending", "accepted"],
            "description": "Membership state."
          },
          "invited_by": {
            "type": ["string", "null"],
            "description": "User who sent the invitation."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the invitation was created.",
            "format": "date-time"
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Time the invitation was last updated.",
            "format": "date-time"
          }
        },
        "required": ["id", "user_id", "email", "role", "status", "invited_by", "created_at", "updated_at"],
        "additionalProperties": false
      },
      "FirmRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Integration request ID.",
            "pattern": "^(?:frq_)?[a-fA-F0-9]{24}$",
            "example": "frq_507f1f77bcf86cd799439011"
          },
          "client_id": {
            "type": "string",
            "description": "Client that receives the request.",
            "pattern": "^(?:fcl_)?[a-fA-F0-9]{24}$",
            "example": "fcl_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": "string",
            "description": "Client organization ID."
          },
          "status": {
            "type": "string",
            "enum": ["pending", "partial", "completed", "expired", "cancelled"],
            "description": "Request state."
          },
          "integrations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Stable request item ID."
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "wallet",
                    "exchange",
                    "bank",
                    "quickbooks",
                    "xero",
                    "netsuite",
                    "ramp",
                    "stripe-ar",
                    "gmail"
                  ],
                  "description": "Requested integration."
                },
                "legal_entity_id": {
                  "type": ["string", "null"],
                  "description": "Legal entity for this integration."
                },
                "status": {
                  "type": "string",
                  "enum": ["pending", "authorized", "declined", "info_submitted"],
                  "description": "Item state."
                },
                "connection_id": {
                  "type": ["string", "null"],
                  "description": "Created connection or source ID."
                },
                "connection_type": {
                  "type": ["string", "null"],
                  "description": "Connection flow used for this item."
                },
                "connected_company_name": {
                  "type": ["string", "null"],
                  "description": "Connected provider company name."
                },
                "decline_reason": {
                  "type": ["string", "null"],
                  "description": "Reason supplied when the item was declined."
                },
                "authorized_at": {
                  "type": ["string", "null"],
                  "description": "Time the item was authorized.",
                  "format": "date-time"
                },
                "declined_at": {
                  "type": ["string", "null"],
                  "description": "Time the item was declined.",
                  "format": "date-time"
                }
              },
              "required": [
                "id",
                "type",
                "legal_entity_id",
                "status",
                "connection_id",
                "connection_type",
                "connected_company_name",
                "decline_reason",
                "authorized_at",
                "declined_at"
              ],
              "additionalProperties": false
            },
            "description": "Requested integrations."
          },
          "email_sent": {
            "type": "boolean",
            "description": "On create or resend, whether that delivery succeeded. On list reads, whether an email has been delivered successfully; email_sent_at records the last successful delivery."
          },
          "email_sent_at": {
            "type": ["string", "null"],
            "description": "Time the request email was sent.",
            "format": "date-time"
          },
          "expires_at": {
            "type": ["string", "null"],
            "description": "Time the request expires.",
            "format": "date-time"
          },
          "requested_at": {
            "type": ["string", "null"],
            "description": "Time the request was submitted.",
            "format": "date-time"
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the request was created.",
            "format": "date-time"
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Time the request was last updated.",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "client_id",
          "organization_id",
          "status",
          "integrations",
          "email_sent",
          "email_sent_at",
          "expires_at",
          "requested_at",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "FirmSettings": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Firm ID.",
            "pattern": "^(?:frm_)?[a-fA-F0-9]{24}$",
            "example": "frm_507f1f77bcf86cd799439011"
          },
          "firm_name": {
            "type": "string",
            "description": "Firm display name."
          },
          "web_address": {
            "type": "string",
            "description": "Entendre subdomain slug.",
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "logo_url": {
            "type": ["string", "null"],
            "description": "Firm logo URL.",
            "format": "uri"
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the firm was created.",
            "format": "date-time"
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Time the firm was last updated.",
            "format": "date-time"
          }
        },
        "required": ["id", "firm_name", "web_address", "logo_url", "created_at", "updated_at"],
        "additionalProperties": false
      },
      "Guidance": {
        "type": "object",
        "properties": {
          "allowed_actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionHint"
            },
            "description": "Actions that you can take now."
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Warning"
            },
            "description": "Warnings about the resource."
          },
          "version": {
            "type": "string",
            "description": "Version of the resource. Use it only when an operation asks for `expected_version`."
          }
        },
        "required": ["allowed_actions", "warnings", "version"],
        "additionalProperties": false
      },
      "IncomeStatement": {
        "type": "object",
        "properties": {
          "ledger_accounts": {
            "type": "array",
            "description": "The ledger accounts on the report, in the same shape as List ledger accounts.",
            "items": {
              "$ref": "#/components/schemas/LedgerAccount"
            }
          },
          "balances": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/components/schemas/FinancialReportRow"
              }
            },
            "description": "Balances by ledger account and accounting period."
          },
          "data_quality": {
            "type": "object",
            "description": "Data-quality checks. The income statement has no checks of its own, so `warnings` is always empty.",
            "properties": {
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Warnings about the report data."
              }
            }
          }
        },
        "required": ["ledger_accounts", "balances"]
      },
      "JournalEntry": {
        "type": "object",
        "required": ["id", "status", "legal_entity_id", "lines", "created_at"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["je_abc123"],
            "description": "Journal ID (`je_…`)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Prefixed organization ID (`org_` prefix).",
            "examples": ["org_abc123"]
          },
          "sequence_number": {
            "type": "string",
            "description": "Human-readable sequence (such as `JE-42`)."
          },
          "status": {
            "type": "string",
            "enum": ["draft", "posted", "reversed", "unposted", "in_progress", "error"],
            "description": "Journal status."
          },
          "originated_by": {
            "type": "string",
            "enum": ["system", "user"],
            "description": "`system` for a journal that Entendre created, `user` for a manual journal."
          },
          "accounting_date": {
            "type": "string",
            "format": "date-time",
            "description": "Accounting date (ISO 8601)."
          },
          "posted_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "`null` for DRAFT entries."
          },
          "memo": {
            "type": ["string", "null"],
            "description": "Memo."
          },
          "source_type": {
            "type": ["string", "null"],
            "enum": [
              "TRANSACTION",
              "ASSETS",
              "REVALUATION",
              "REVERSE_REVALUATION",
              "NIURAL_INVOICE",
              "ACCRUAL",
              "MANUAL",
              "BILL_EXPENSE",
              "QUICKBOOKS",
              "STRIPE_INVOICE",
              "STRIPE_PAYMENT",
              "STRIPE_FEE",
              "STRIPE_DISPUTE",
              "CASH_APPLICATION",
              null
            ],
            "description": "What created this entry. `null` if not set."
          },
          "sync_date": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this entry was last synced to its external GL; `null` if never synced. Set on list responses; `null` in the response of an operation that changes one entry."
          },
          "last_synced_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this entry was last sent to the external GL. Unlike `sync_date`, it stays after an unsync and changes only on the next sync. `null` if never synced."
          },
          "last_unsynced_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "When this entry was last removed (unsynced) from the external GL. It is never cleared. `last_unsynced_at > last_synced_at` means the entry is currently out of the GL."
          },
          "legal_entity_id": {
            "type": "string",
            "description": "Legal entity ID (`le_…`)."
          },
          "transaction_id": {
            "type": ["string", "null"],
            "description": "Linked transaction (`txn_…`), or `null`."
          },
          "transaction_sequence_number": {
            "type": ["string", "null"],
            "description": "Sequence number (such as `OT-1234`) of the source transaction, when populated. `null` on responses that don't expand the transaction."
          },
          "template_id": {
            "type": ["string", "null"],
            "description": "Template used to generate this entry, if applicable (`tpl_` prefix). `null` for manual or classification-based entries."
          },
          "accounting_period_id": {
            "type": ["string", "null"],
            "description": "Accounting period this entry falls in (`ap_` prefix). `null` if not assigned to a period."
          },
          "classification": {
            "type": ["string", "null"],
            "description": "Transaction type used to derive the journal lines."
          },
          "tag_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tag IDs (`tag_…`)."
          },
          "reversal_chain": {
            "type": "object",
            "properties": {
              "previous_entry_id": {
                "type": ["string", "null"],
                "description": "Journal that this journal reverses, or `null`."
              },
              "next_entry_id": {
                "type": ["string", "null"],
                "description": "Journal that reverses this journal, or `null`."
              }
            },
            "description": "Links to the journals before and after this one in a reversal chain."
          },
          "period_auto_reassigned": {
            "type": "boolean",
            "description": "`true` when the accounting date was in a closed period, so the journal moved to the current open period."
          },
          "intended_accounting_date": {
            "type": ["string", "null"],
            "description": "When period_auto_reassigned is true, the entry's own accounting date (whose true period is closed); null otherwise."
          },
          "legal_entity_auto_assigned": {
            "type": "boolean",
            "description": "`true` when the journal had no legal entity, so Entendre assigned the only active legal entity."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalEntryLine"
            },
            "description": "Journal lines."
          },
          "is_sync": {
            "type": "boolean",
            "description": "Whether this entry has been synced to an external GL (QuickBooks, Xero, NetSuite, DualEntry, Campfire)."
          },
          "latest_gl_sync_attempt": {
            "type": ["object", "null"],
            "description": "Most recent GL sync attempt for this entry; `null` if a sync has never been attempted.",
            "properties": {
              "id": {
                "type": ["string", "null"],
                "description": "Sync attempt ID (`jesa_…`), or `null` for older attempts.",
                "examples": ["jesa_abc123"]
              },
              "gl_type": {
                "type": ["string", "null"],
                "enum": ["QUICKBOOKS", "XERO", "NETSUITE", "DUALENTRY", "CAMPFIRE", null],
                "description": "Target GL the sync attempt was made against."
              },
              "external_type": {
                "type": ["string", "null"],
                "description": "Provider-specific transaction type used (such as QBO Purchase, Deposit, BillPayment)."
              },
              "external_id": {
                "type": ["string", "null"],
                "description": "ID of the posted entry in the GL; `null` for failed or pending attempts."
              },
              "error_type": {
                "type": ["string", "null"],
                "enum": [
                  "AUTHENTICATION",
                  "MAPPING_MISSING",
                  "VALIDATION",
                  "UNKNOWN",
                  "DUPLICATE_DETECTED",
                  "DOC_NUMBER_COLLISION",
                  null
                ],
                "description": "Category of the failure, if the latest attempt errored; `null` when the attempt did not error."
              },
              "error_details": {
                "type": ["string", "null"],
                "description": "Human-readable detail for the failure, if any."
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the journal was created (ISO 8601)."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the journal was last updated (ISO 8601)."
          }
        }
      },
      "JournalEntryLine": {
        "type": "object",
        "required": ["id", "ledger_account_id", "legal_entity_id", "credit_or_debit", "amount", "currency"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["jel_def456"],
            "description": "Journal line ID."
          },
          "ledger_account_id": {
            "type": "string",
            "description": "Ledger account ID (`lac_…`)."
          },
          "legal_entity_id": {
            "type": "string",
            "description": "Legal entity this line belongs to. Typically inherited from the parent journal entry or derived from the transaction's source, but can differ in multi-entity scenarios."
          },
          "credit_or_debit": {
            "type": "string",
            "enum": ["DEBIT", "CREDIT"],
            "description": "`DEBIT` or `CREDIT`."
          },
          "amount": {
            "type": "string",
            "description": "Decimal string."
          },
          "currency": {
            "type": "string",
            "description": "Currency of the line amount."
          },
          "memo": {
            "type": ["string", "null"],
            "description": "Memo."
          },
          "tag_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tag IDs (`tag_…`)."
          }
        }
      },
      "LedgerAccount": {
        "type": "object",
        "required": ["id", "name", "type", "normal_balance", "is_postable", "is_archived", "created_at"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["lac_789abc"],
            "description": "Ledger account ID (`lac_…`)."
          },
          "name": {
            "type": "string",
            "description": "Ledger account name."
          },
          "type": {
            "type": "string",
            "enum": ["Asset", "Liability", "Equity", "Income", "Expense"],
            "description": "Account type."
          },
          "normal_balance": {
            "type": "string",
            "enum": ["debit", "credit"],
            "description": "Computed from type. Asset/Expense = debit, Liability/Equity/Income = credit."
          },
          "sequence_number": {
            "type": ["integer", "null"],
            "description": "Chart-of-accounts ordering code. Null when the stored value is not a valid non-negative integer."
          },
          "parent_account_id": {
            "type": ["string", "null"],
            "description": "Parent account (`lac_…`), or `null` for a top-level account."
          },
          "is_postable": {
            "type": "boolean",
            "description": "`true` for a postable child account that accepts journal lines; `false` for a parent grouping account."
          },
          "is_clearing_account": {
            "type": "boolean",
            "description": "`true` for a clearing account used for internal transfers and payables."
          },
          "is_archived": {
            "type": "boolean",
            "description": "`true` when the account is archived. Earlier journal entries can still refer to it. List ledger accounts excludes archived accounts unless you set `include_archived=true`."
          },
          "archived_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the account was archived, or `null` when it is not archived."
          },
          "asset_type": {
            "type": ["string", "null"],
            "description": "Asset or currency that the account tracks, such as `ETH` or `USD`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the ledger account was created (ISO 8601)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was last updated (ISO 8601)."
          }
        }
      },
      "LegalEntity": {
        "type": "object",
        "required": ["id", "name", "entity_type", "status", "base_currency", "created_at"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["le_456def"],
            "description": "Legal entity ID (`le_…`)."
          },
          "name": {
            "type": "string",
            "description": "Legal entity name."
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "C-CORP",
              "S-CORP",
              "LLC",
              "LP",
              "LLP",
              "GmbH",
              "Ltd",
              "PLC",
              "Foundation",
              "Trust",
              "Non-Profit",
              "Sole Proprietorship",
              "DAO",
              "Other"
            ],
            "description": "Legal entity type."
          },
          "status": {
            "type": "string",
            "enum": ["active", "archived"],
            "description": "Legal entity status."
          },
          "base_currency": {
            "type": "string",
            "description": "Base reporting currency (ISO 4217)."
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "address_string": {
            "type": ["string", "null"],
            "description": "Address as one line of text. `address` takes precedence when both are set."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the legal entity was created (ISO 8601)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was last updated (ISO 8601)."
          }
        }
      },
      "OrganizationFull": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "examples": ["org_abc123"],
            "description": "Organization ID (`org_…`)."
          },
          "name": {
            "type": "string",
            "description": "Organization name."
          },
          "web_address": {
            "type": ["string", "null"],
            "description": "Organization website URL."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone of the organization, such as `America/New_York`."
          },
          "time_format": {
            "type": "string",
            "enum": ["hr12", "hr24"],
            "description": "Clock format for display: `hr12` or `hr24`."
          },
          "onboarding_status": {
            "type": ["string", "null"],
            "description": "Onboarding status of the organization."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the organization was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the organization was last updated (ISO 8601)."
          },
          "logo_url": {
            "type": ["string", "null"],
            "description": "Organization logo URL; null when no logo is set."
          }
        },
        "required": ["id", "name"]
      },
      "OrganizationMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Prefixed member ID (`mbr_`).",
            "examples": ["mbr_abc123"]
          },
          "user_id": {
            "type": ["string", "null"],
            "examples": ["usr_def456"],
            "description": "User ID of the member, or `null` before the invitation is accepted."
          },
          "email": {
            "type": ["string", "null"],
            "description": "Masked by default as <first-char>***@<domain>. Set include_pii=true to request the full address."
          },
          "name": {
            "type": ["string", "null"],
            "description": "Member name."
          },
          "role": {
            "type": ["string", "null"],
            "enum": ["admin", "accountant", "auditor", "analyst", null],
            "description": "Organization role, lowercased."
          },
          "status": {
            "type": ["string", "null"],
            "description": "Membership status: `accepted` or `pending`."
          },
          "invited_by": {
            "type": ["string", "null"],
            "examples": ["usr_ghi789"],
            "description": "User who sent the invitation."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the membership was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the membership was last updated (ISO 8601)."
          }
        },
        "required": ["id"]
      },
      "RealizedGains": {
        "type": "object",
        "required": [
          "asset_type",
          "asset_record",
          "date_received",
          "quantity",
          "remaining_quantity",
          "cost_basis",
          "currency",
          "disposals"
        ],
        "properties": {
          "asset_type": {
            "type": "string",
            "description": "Token / currency symbol (such as `ETH`, `USDC`)."
          },
          "asset_record": {
            "type": "string",
            "description": "Asset record ID."
          },
          "date_received": {
            "type": "string",
            "format": "date-time",
            "description": "ISO timestamp when the lot was acquired. The field name matches the schedule of dispositions report."
          },
          "quantity": {
            "type": "string",
            "description": "Original quantity acquired, as a decimal string."
          },
          "remaining_quantity": {
            "type": "string",
            "description": "Quantity still held after all disposals."
          },
          "cost_basis": {
            "type": "string",
            "description": "Cost basis per unit, as a decimal string."
          },
          "currency": {
            "type": "string",
            "description": "Currency of the proceeds and cost basis.",
            "example": "USD"
          },
          "disposals": {
            "type": "array",
            "description": "Disposal events for this lot.",
            "items": {
              "type": "object",
              "required": ["sale_date", "quantity_sold", "sale_price"],
              "properties": {
                "sale_date": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Date of the disposal (ISO 8601)."
                },
                "quantity_sold": {
                  "type": "string",
                  "description": "Quantity disposed on this event."
                },
                "sale_price": {
                  "type": "string",
                  "description": "Proceeds per unit, as a decimal string."
                }
              }
            }
          }
        }
      },
      "ReportContext": {
        "type": "object",
        "properties": {
          "start_date": {
            "type": ["string", "null"],
            "description": "Inclusive requested start, when applicable."
          },
          "end_date": {
            "type": ["string", "null"],
            "description": "Exclusive end, when applicable."
          },
          "as_of": {
            "type": ["string", "null"],
            "description": "Cutoff time, when applicable."
          },
          "currency": {
            "type": "string",
            "description": "Reporting currency.",
            "example": "USD"
          },
          "legal_entity_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Legal entity ID (`le_…`).",
              "example": "le_507f1f77bcf86cd799439011"
            },
            "description": "Legal entities in the report."
          },
          "basis": {
            "type": "string",
            "description": "Accounting ledger, live provider position or unclassified transaction cash flow.",
            "enum": ["ledger", "live", "transactions"]
          },
          "generated_at": {
            "type": "string",
            "description": "ISO 8601 UTC timestamp.",
            "format": "date-time",
            "example": "2026-08-31T12:00:00Z"
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Warning"
            },
            "description": "Warnings about the report."
          },
          "date_boundary": {
            "type": "string",
            "description": "Effective date-boundary rule used for this report.",
            "enum": ["inclusive_end", "exclusive_end", "as_of", "accounting_period"]
          }
        },
        "required": ["currency", "legal_entity_ids", "basis", "generated_at", "warnings", "date_boundary"],
        "additionalProperties": false
      },
      "ResourceLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID of the referenced resource."
          },
          "url": {
            "type": "string",
            "description": "Relative API path."
          },
          "type": {
            "type": "string",
            "description": "Resource type."
          }
        },
        "required": ["id", "url", "type"],
        "additionalProperties": false
      },
      "Revaluation": {
        "type": "object",
        "description": "An asset-revaluation job. The job posts its journal entries directly; there is no draft, review or apply stage.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Job ID (`job_…`).",
            "example": "job_507f1f77bcf86cd799439011"
          },
          "period_id": {
            "type": "string",
            "description": "Accounting period ID (`ap_…`).",
            "example": "ap_507f1f77bcf86cd799439011"
          },
          "status": {
            "type": "string",
            "enum": ["started", "in_progress", "completed", "job_failed", "canceled", "hanged"],
            "description": "Job status."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the job was created (ISO 8601)."
          },
          "completed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Set when the job ends; `null` while it runs."
          },
          "message": {
            "type": ["string", "null"],
            "description": "Detail about the final state, such as a failure reason; `null` otherwise."
          }
        },
        "required": ["id", "period_id", "status", "created_at", "completed_at", "message"],
        "additionalProperties": false
      },
      "Review": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Review status. `pending` does not approve the run.",
            "enum": ["not_required", "pending", "approved", "rejected"]
          },
          "reviewer_user_id": {
            "type": ["string", "null"],
            "description": "Assigned organization user."
          },
          "review_url": {
            "type": ["string", "null"],
            "description": "Dashboard URL for an authorized user to complete a required review. Present when status is pending; null when no review is required."
          },
          "reviewed_at": {
            "type": ["string", "null"],
            "description": "ISO timestamp of decision."
          }
        },
        "required": ["status", "reviewer_user_id", "review_url", "reviewed_at"],
        "additionalProperties": false
      },
      "Source": {
        "type": "object",
        "required": [
          "id",
          "source_type",
          "organization_id",
          "legal_entity_id",
          "name",
          "status",
          "created_at",
          "updated_at",
          "detail"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Source ID.",
            "example": "src_507f1f77bcf86cd799439011"
          },
          "source_type": {
            "type": "string",
            "description": "Source type. It determines the fields in `detail`.",
            "enum": [
              "exchange",
              "staking",
              "niural",
              "raincard",
              "ramp_card",
              "ramp_bank_account",
              "manual_bank",
              "wallet",
              "plaid_account"
            ]
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "description": "Legal entity of the source (`le_…`), or `null`."
          },
          "name": {
            "type": ["string", "null"],
            "description": "Display name, such as the card nickname or the bank name and last four digits."
          },
          "status": {
            "type": "string",
            "description": "Source status.",
            "enum": ["active", "archived"]
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the source was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the source was last updated (ISO 8601)."
          },
          "detail": {
            "$ref": "#/components/schemas/SourceDetail"
          },
          "group_id": {
            "type": ["string", "null"],
            "description": "Prefixed `sgp_` id of the source group this source belongs to, or null when it is not in one. Always null for `staking`, which cannot be grouped."
          },
          "group": {
            "description": "The full source group, present only when the request passed `expand=group`. Null when the source is ungrouped.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/V1SourceGroup"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "SourceDetail": {
        "type": "object",
        "properties": {
          "address": {
            "type": ["string", "null"],
            "description": "Wallet address where relevant."
          },
          "chain": {
            "type": ["string", "null"],
            "description": "Network identifier."
          },
          "bank_name": {
            "type": ["string", "null"],
            "description": "Bank institution."
          },
          "account_name": {
            "type": ["string", "null"],
            "description": "Account label."
          },
          "account_number_last_four": {
            "type": ["string", "null"],
            "description": "Masked last four only."
          },
          "card_last4": {
            "type": ["string", "null"],
            "description": "Masked card last four."
          },
          "exchange_source_type": {
            "type": ["string", "null"],
            "description": "Exchange provider."
          },
          "has_credentials": {
            "type": "boolean",
            "description": "Whether credentials are stored. The credential is never returned."
          },
          "credential_status": {
            "type": ["string", "null"],
            "description": "Provider authorization state."
          },
          "ledger_account_id": {
            "type": ["string", "null"],
            "description": "The single ledger account assigned to this source. Null when no account is assigned.",
            "example": "lac_507f1f77bcf86cd799439011"
          }
        },
        "additionalProperties": false,
        "description": "Details for the source type."
      },
      "Tag": {
        "type": "object",
        "required": ["id", "organization_id", "key", "value", "status", "created_at"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["tag_456ghi"],
            "description": "Tag ID (`tag_…`)."
          },
          "organization_id": {
            "type": "string",
            "description": "Prefixed organization ID.",
            "examples": ["org_abc123"]
          },
          "key": {
            "type": "string",
            "description": "Free-form tag key. Common keys: `Customer`, `Supplier`, `Cost Center`, `Class`, `Staff`, `Product`, `Bank Account`."
          },
          "value": {
            "type": "string",
            "description": "Tag value, such as `Acme Corp`."
          },
          "status": {
            "type": "string",
            "description": "Usable or retained for history.",
            "enum": ["active", "archived"]
          },
          "usage_count": {
            "type": "integer",
            "description": "Approximate number of records with the tag. It can be lower than the actual number."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the tag was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "description": "Timestamp of last tag change."
          }
        }
      },
      "TaxLot": {
        "type": "object",
        "properties": {
          "asset_id": {
            "type": "string",
            "description": "Asset ID (`ast_…`).",
            "example": "ast_507f1f77bcf86cd799439011"
          },
          "asset_type": {
            "type": "string",
            "description": "Asset type, such as `ETH`.",
            "example": "ETH"
          },
          "source_id": {
            "type": ["string", "null"],
            "description": "Source that holds the lot."
          },
          "date_received": {
            "type": "string",
            "description": "ISO 8601 UTC timestamp.",
            "format": "date-time",
            "example": "2026-08-31T12:00:00Z"
          },
          "quantity": {
            "type": "string",
            "description": "Decimal string; parse with a decimal library, not binary floating point.",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "remaining_quantity": {
            "type": "string",
            "description": "Decimal string; parse with a decimal library, not binary floating point.",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "cost_basis": {
            "type": "string",
            "description": "Cost per unit, in the lot currency. Decimal string; parse with a decimal library, not binary floating point.",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "remaining_cost_basis": {
            "type": "string",
            "description": "Cost basis of the remaining quantity at as_of: cost_basis × remaining_quantity, in the lot currency. Decimal string; parse with a decimal library, not binary floating point.",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "currency": {
            "type": "string",
            "description": "Basis currency.",
            "example": "USD"
          },
          "method": {
            "type": "string",
            "description": "Cost-basis allocation method.",
            "example": "FIFO"
          },
          "disposition_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Disposition ID."
            },
            "description": "Dispositions of this lot."
          }
        },
        "required": [
          "asset_id",
          "asset_type",
          "source_id",
          "date_received",
          "quantity",
          "remaining_quantity",
          "cost_basis",
          "remaining_cost_basis",
          "currency",
          "method",
          "disposition_ids"
        ],
        "additionalProperties": false
      },
      "Transaction": {
        "type": "object",
        "required": ["id", "account_id", "organization_id", "legal_entity_id", "source_class", "external", "internal"],
        "properties": {
          "id": {
            "type": "string",
            "examples": ["txn_abc123"],
            "description": "Transaction ID (`txn_…`)."
          },
          "sequence_number": {
            "type": ["string", "null"],
            "description": "Sequence number, such as `OT-1234`. It is assigned shortly after creation, so it is `null` in the create response."
          },
          "account_id": {
            "type": ["string", "null"],
            "description": "ID of the source of the transaction. Use it in the `account_id` filter of List transactions."
          },
          "organization_id": {
            "type": "string",
            "description": "Organization ID (`org_…`)."
          },
          "legal_entity_id": {
            "type": "string",
            "description": "Legal entity ID (`le_…`)."
          },
          "source_class": {
            "type": "string",
            "enum": ["crypto", "fiat", "card", "exchange", "other"],
            "description": "Kind of source: `crypto`, `fiat`, `card`, `exchange` or `other`."
          },
          "provider": {
            "type": "string",
            "enum": [
              "wallet",
              "fireblocks",
              "plaid",
              "ramp",
              "rain",
              "kraken",
              "binance",
              "coinbase",
              "coinbase_prime",
              "coinbase_exchange",
              "coinbase_international",
              "deribit",
              "bitmex",
              "bybit",
              "kucoin",
              "gate",
              "mexc",
              "gemini",
              "woo",
              "okx",
              "bitfinex",
              "circle",
              "canton",
              "niural",
              "finch_payroll"
            ],
            "description": "Provider that the transaction came from."
          },
          "vendor": {
            "type": ["string", "null"],
            "description": "Counterparty name, or `null` when unknown. Can be bank text when there is no merchant name."
          },
          "provider_category": {
            "type": ["string", "null"],
            "description": "Raw category metadata assigned by Ramp or Plaid. It is not accounting treatment."
          },
          "external": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "string",
                "format": "date-time",
                "description": "Time of the transaction (ISO 8601)."
              },
              "description": {
                "type": "string",
                "description": "Description from the provider."
              },
              "direction": {
                "type": "string",
                "enum": ["credit", "debit"],
                "description": "`credit` for money in, `debit` for money out, relative to the source."
              },
              "quantity": {
                "type": ["object", "null"],
                "description": "Token quantity breakdown (crypto only). `null` for fiat/card transactions.",
                "properties": {
                  "gross": {
                    "type": "string",
                    "description": "Gross token quantity before fees. For a 1.5 ETH transfer with 0.003 ETH gas, `gross` is `\"1.5\"`."
                  },
                  "fee": {
                    "type": "string",
                    "description": "Token fee deducted (such as gas in native token). Same unit as `currency`."
                  },
                  "net": {
                    "type": "string",
                    "description": "Net token quantity after fees (`gross - fee`)."
                  }
                }
              },
              "currency": {
                "type": "string",
                "description": "Token symbol (crypto) or ISO 4217 (fiat)."
              },
              "value_fiat": {
                "$ref": "#/components/schemas/ValueFiat"
              }
            },
            "description": "The transaction as the provider reported it."
          },
          "crypto": {
            "type": ["object", "null"],
            "description": "Present when `source_class` is `crypto`. `null` otherwise.",
            "properties": {
              "chain": {
                "type": "string",
                "description": "Blockchain network, such as `eth`."
              },
              "asset_type": {
                "type": "string",
                "description": "Asset symbol, such as `ETH`."
              },
              "from_address": {
                "type": "string",
                "description": "Sending address."
              },
              "to_address": {
                "type": "string",
                "description": "Receiving address."
              },
              "hash": {
                "type": "string",
                "description": "On-chain transaction hash."
              }
            }
          },
          "bank": {
            "type": ["object", "null"],
            "description": "Bank details for fiat transactions.",
            "properties": {
              "bank_name": {
                "type": "string",
                "description": "Bank name."
              },
              "account_last4": {
                "type": "string",
                "description": "Last four digits of the bank account."
              },
              "counterparty_name": {
                "type": "string",
                "description": "Counterparty name from the bank."
              },
              "merchant_id": {
                "type": "string",
                "description": "Stable merchant ID from Plaid. Use it to group transactions by merchant."
              },
              "category_version": {
                "type": "string",
                "description": "Version of the Plaid category taxonomy."
              },
              "category_confidence": {
                "type": "string",
                "description": "Plaid confidence in the category."
              },
              "running_balance": {
                "type": "string",
                "description": "Account balance after the transaction, when the bank reports it (decimal string)."
              },
              "correction_status": {
                "type": "string",
                "description": "Status of a bank correction to this transaction."
              },
              "correction_reason": {
                "type": "string",
                "description": "Reason for the bank correction."
              },
              "bank_removed": {
                "type": "boolean",
                "description": "`true` when the bank removed the transaction."
              },
              "counterparties": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Counterparty name."
                    },
                    "entity_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Plaid entity ID of the counterparty."
                    },
                    "type": {
                      "type": "string",
                      "nullable": true,
                      "description": "Counterparty type, such as merchant or payment intermediary."
                    },
                    "confidence": {
                      "type": "string",
                      "nullable": true,
                      "description": "Plaid confidence in the counterparty."
                    }
                  }
                },
                "description": "Counterparties that Plaid identified."
              }
            }
          },
          "card": {
            "type": ["object", "null"],
            "description": "Present when `source_class` is `card`. `null` otherwise.",
            "properties": {
              "merchant_name": {
                "type": "string",
                "description": "Merchant name."
              },
              "merchant_category": {
                "type": "string",
                "description": "Merchant category."
              },
              "card_last4": {
                "type": "string",
                "description": "Last four digits of the card."
              },
              "employee_name": {
                "type": "string",
                "description": "Cardholder name."
              }
            }
          },
          "internal": {
            "type": "object",
            "properties": {
              "transaction_type": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/TransactionCategory"
                  }
                ],
                "description": "Economic transaction type. The linked journal shows the accounting treatment."
              },
              "status": {
                "type": "string",
                "enum": ["pending", "posted", "spam"],
                "description": "`pending`, `posted` or `spam`."
              },
              "memo": {
                "type": ["string", "null"],
                "description": "Memo."
              },
              "journal_entry_id": {
                "type": ["string", "null"],
                "description": "Prefixed ID of the associated journal entry (such as `je_abc123`). `null` if no journal entry has been posted."
              }
            },
            "description": "How Entendre records the transaction."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the transaction was imported (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "ISO 8601 timestamp of the last update."
          },
          "tag_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Tag ID (`tag_…`).",
              "example": "tag_507f1f77bcf86cd799439011"
            },
            "maxItems": 100,
            "uniqueItems": true,
            "description": "Tag IDs (`tag_…`)."
          }
        }
      },
      "TransactionCategory": {
        "type": "string",
        "description": "Economic transaction type. Some values contain spaces, such as `INTERNAL TRANSFER`.",
        "enum": [
          "DEPOSIT",
          "WITHDRAWAL",
          "SWAP",
          "NON_TAXABLE_CONVERSION",
          "BRIDGE",
          "INTERCOMPANY TRANSFER",
          "INTERNAL TRANSFER",
          "FEE",
          "MINTING",
          "STAKING_REWARD",
          "VALIDATOR_REWARD",
          "INVOICE",
          "BILL",
          "CLAIM REWARD",
          "BORROW",
          "REPAYMENT",
          "RESERVES CHANGE",
          "REALIZED_PNL",
          "INCOME",
          "EXPENSE",
          "REFUND",
          "CHARGEBACK",
          "NFT",
          "SPAM",
          "UNKNOWN"
        ]
      },
      "TransactionInsightDataQuality": {
        "type": "object",
        "description": "Transactions that the figures exclude, and why. Bank removals and amounts without a USD value are excluded.",
        "required": [
          "status",
          "window_transaction_count",
          "excluded_spam_count",
          "excluded_spam_by_currency",
          "excluded_non_pl_classification_count",
          "excluded_non_pl_classification_by_currency",
          "no_posted_journal_entry_count",
          "warnings",
          "excluded_bank_removed_count",
          "excluded_bank_removed_by_currency",
          "excluded_currency_valuation_count",
          "excluded_currency_valuation_by_currency",
          "bank_correction_review_count",
          "plaid_enrichment"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": ["ok", "warnings", "unavailable"],
            "description": "`ok`, `warnings`, or `unavailable` when the exclusions could not be calculated."
          },
          "window_transaction_count": {
            "type": "integer",
            "description": "Transactions in the window, including excluded ones."
          },
          "excluded_spam_count": {
            "type": "integer",
            "description": "Spam-flagged transactions excluded from the figures."
          },
          "excluded_spam_by_currency": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionInsightExclusionByCurrency"
            },
            "description": "Excluded spam transactions, by currency. Amounts are decimal strings."
          },
          "excluded_non_pl_classification_count": {
            "type": "integer",
            "description": "Transactions excluded because their type is not income or expense, such as transfers and swaps."
          },
          "excluded_non_pl_classification_by_currency": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionInsightExclusionByCurrency"
            },
            "description": "Excluded transfers and other non-income, non-expense transactions, by currency."
          },
          "no_posted_journal_entry_count": {
            "type": "integer",
            "description": "Transactions in the window with no posted journal. Same as the `has_posted_journal_entry=false` filter."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "[WARNING]-prefixed prose for each non-zero excluded bucket. Surface these whenever material."
          },
          "excluded_bank_removed_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Transactions excluded because the bank removed them."
          },
          "excluded_bank_removed_by_currency": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionInsightExclusionByCurrency"
            },
            "description": "Bank removals grouped by currency."
          },
          "excluded_currency_valuation_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Transactions excluded because they have no USD value."
          },
          "excluded_currency_valuation_by_currency": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionInsightExclusionByCurrency"
            },
            "description": "Transactions without a USD value, grouped by currency."
          },
          "bank_correction_review_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Transactions with a bank correction to review."
          },
          "plaid_enrichment": {
            "type": "object",
            "description": "Coverage of Plaid enrichment in the window.",
            "required": [
              "transaction_count",
              "merchant_identity_count",
              "running_balance_count",
              "category_versions",
              "category_confidence"
            ],
            "properties": {
              "transaction_count": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions with Plaid enrichment."
              },
              "merchant_identity_count": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions with a Plaid merchant ID."
              },
              "running_balance_count": {
                "type": "integer",
                "minimum": 0,
                "description": "Transactions with a running balance."
              },
              "category_versions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["version", "transaction_count"],
                  "properties": {
                    "version": {
                      "type": "string",
                      "description": "Plaid category version."
                    },
                    "transaction_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Transactions with this version."
                    }
                  }
                },
                "description": "Transactions by Plaid category version."
              },
              "category_confidence": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["confidence", "transaction_count"],
                  "properties": {
                    "confidence": {
                      "type": "string",
                      "description": "Plaid confidence level."
                    },
                    "transaction_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Transactions with this confidence."
                    }
                  }
                },
                "description": "Transactions by Plaid category confidence."
              }
            }
          }
        }
      },
      "TransactionInsightExclusionByCurrency": {
        "type": "object",
        "required": ["currency", "transaction_count", "amount"],
        "properties": {
          "currency": {
            "type": "string",
            "description": "Currency code from the excluded transaction rows. `UNKNOWN` means the source row has no currency."
          },
          "transaction_count": {
            "type": "integer",
            "description": "Excluded transactions in this currency block."
          },
          "amount": {
            "type": "string",
            "description": "Gross value for this currency (decimal string, 2 decimal places)."
          }
        }
      },
      "TreasuryBalance": {
        "type": "object",
        "description": "One source group: a wallet, an exchange account, or a bank account, with its tokens nested.",
        "properties": {
          "source_id": {
            "type": ["string", "null"],
            "description": "Source ID (`fac_…`) of the wallet, exchange account or bank account. `null` for a Plaid bank group."
          },
          "source_class": {
            "type": "string",
            "enum": ["crypto", "exchange", "bank"],
            "description": "`crypto`, `exchange` or `bank`."
          },
          "chain": {
            "type": ["string", "null"],
            "description": "Blockchain network, for a wallet."
          },
          "provider": {
            "type": ["string", "null"],
            "description": "Bank institution name or exchange type; null for a crypto wallet."
          },
          "alias": {
            "type": ["string", "null"],
            "description": "Display name of the source."
          },
          "entity_name": {
            "type": ["string", "null"],
            "description": "Legal entity name."
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "description": "Legal entity ID (`le_…`)."
          },
          "total_fiat": {
            "type": "string",
            "description": "Sum of this source's token fiat values."
          },
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TreasuryBalanceToken"
            },
            "description": "Balances by token."
          },
          "as_of": {
            "type": ["string", "null"],
            "description": "Provider balance update time for this source. Null when the provider supplies no update time.",
            "format": "date-time",
            "example": "2026-08-31T12:00:00Z"
          },
          "basis": {
            "type": "string",
            "enum": ["live"],
            "description": "Always `live`."
          },
          "availability": {
            "type": "string",
            "description": "Always `available`. A source that cannot be read appears in `context.warnings`.",
            "enum": ["available"]
          },
          "warnings": {
            "type": "array",
            "items": {},
            "description": "Currently always empty. Issues for a whole source are in `context.warnings`."
          }
        },
        "required": ["source_class", "chain", "total_fiat", "tokens"]
      },
      "TreasuryBalanceToken": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "description": "Token symbol."
          },
          "balance": {
            "type": "string",
            "description": "Quantity held (decimal string)."
          },
          "fiat_value": {
            "type": "string",
            "description": "Value in USD (decimal string)."
          },
          "is_native": {
            "type": "boolean",
            "description": "`true` for the native token of the chain."
          }
        },
        "required": ["symbol", "balance", "fiat_value", "is_native"]
      },
      "TreasuryBalancesWarning": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": ["on_chain_tokens", "exchanges", "bank_accounts"],
            "description": "Which balances are affected."
          },
          "reason": {
            "type": "string",
            "enum": ["upstream_error", "not_supported_yet", "no_snapshot", "missing_from_fetch", "valuation_gap"],
            "description": "Why the balances are missing or incomplete."
          },
          "message": {
            "type": "string",
            "description": "Explanation of the warning."
          },
          "fallback_hint": {
            "type": "string",
            "description": "What to do instead."
          }
        },
        "required": ["source", "reason", "message", "fallback_hint"]
      },
      "TrialBalance": {
        "type": "object",
        "properties": {
          "meta": {
            "type": "object",
            "description": "Account counts after row filtering.",
            "properties": {
              "zero_rows_omitted": {
                "type": "boolean",
                "description": "`true` when all-zero accounts were filtered out of `ledger_accounts` and `balances`."
              },
              "account_count": {
                "type": "integer",
                "description": "Accounts present in this response."
              },
              "total_account_count": {
                "type": "integer",
                "description": "Accounts before filtering: the size of the organization's chart of accounts. `data_quality` totals are computed over this unfiltered set."
              }
            }
          },
          "ledger_accounts": {
            "type": "array",
            "description": "Accounts in the report. When `include_zero_rows` is `false`, only accounts with a balance or movement, and their parents.",
            "items": {
              "$ref": "#/components/schemas/LedgerAccount"
            }
          },
          "balances": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "ledger_account_id": {
                  "type": "string",
                  "description": "Ledger account (`lac_…`)."
                },
                "opening_balance": {
                  "type": "string",
                  "description": "Balance at the start of the window (decimal string)."
                },
                "closing_balance": {
                  "type": "string",
                  "description": "Balance at the end of the window (decimal string)."
                },
                "current_balance": {
                  "type": "string",
                  "description": "Current balance (decimal string)."
                },
                "debits": {
                  "type": "string",
                  "description": "Debits in the window (decimal string)."
                },
                "credits": {
                  "type": "string",
                  "description": "Credits in the window (decimal string)."
                }
              }
            },
            "description": "Balances by ledger account."
          },
          "data_quality": {
            "type": "object",
            "description": "Checks on the trial balance. Use `is_balanced` and `is_empty`; the warning text can change.",
            "properties": {
              "is_balanced": {
                "type": "boolean",
                "description": "Total debits equal total credits across the leaf accounts, within half a cent. This is necessary but not sufficient; see `is_empty`."
              },
              "is_empty": {
                "type": "boolean",
                "description": "`true` when the report has no ledger accounts or every account is zero."
              },
              "total_debits": {
                "type": "string",
                "description": "Total debits across the leaf accounts (decimal string)."
              },
              "total_credits": {
                "type": "string",
                "description": "Total credits across the leaf accounts (decimal string)."
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Human-readable `[WARNING]` strings for any raised condition (does-not-foot, or empty)."
              }
            }
          }
        },
        "required": ["ledger_accounts", "balances"]
      },
      "V1CashApplication": {
        "type": "object",
        "description": "A deposit and the invoices that it pays.",
        "required": [
          "id",
          "organization_id",
          "status",
          "stripe_status",
          "total_amount",
          "applied_amount",
          "unapplied_amount",
          "allocations",
          "etag"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Cash application ID."
          },
          "organization_id": {
            "type": "string",
            "description": "`org_…`"
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "description": "`le_…`"
          },
          "deposit_transaction_id": {
            "type": ["string", "null"],
            "description": "Deposit transaction (`txn_…`)."
          },
          "status": {
            "type": "string",
            "enum": ["draft", "applied", "partially_applied", "voided"],
            "description": "Cash application status."
          },
          "stripe_status": {
            "type": ["string", "null"],
            "enum": ["pending", "synced", "failed", null],
            "description": "Stripe sync status: `pending`, `synced` or `failed`."
          },
          "match_type": {
            "type": ["string", "null"],
            "enum": ["exact", "multi_invoice", "tolerance", "manual", null],
            "description": "How the invoices were matched."
          },
          "total_amount": {
            "type": "string",
            "description": "Deposit amount (decimal string)."
          },
          "applied_amount": {
            "type": "string",
            "description": "Sum of `allocations[].amount`."
          },
          "unapplied_amount": {
            "type": "string",
            "description": "Amount not yet applied (decimal string)."
          },
          "deposit_memo": {
            "type": ["string", "null"],
            "description": "Deposit memo."
          },
          "txn_date": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Deposit date (ISO 8601)."
          },
          "allocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/V1CashApplicationAllocation"
            },
            "description": "Invoice allocations."
          },
          "applied_by": {
            "type": ["string", "null"],
            "description": "User who applied the cash application."
          },
          "journal_entry_id": {
            "type": ["string", "null"],
            "description": "Journal (`je_…`) created when the cash application is applied."
          },
          "stripe_marked_paid_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the invoices were marked as paid in Stripe."
          },
          "confirmed_by": {
            "type": ["string", "null"],
            "description": "`usr_…`"
          },
          "confirmed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the cash application was confirmed."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the cash application was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the cash application was last updated (ISO 8601)."
          },
          "error_message": {
            "type": ["string", "null"],
            "description": "Why the last operation failed, or `null`."
          },
          "non_customer_resolution": {
            "type": ["object", "null"],
            "description": "Evidence for a non-customer deposit already booked in Campfire. The application shows as `voided` and has no cash-application journal.",
            "properties": {
              "gl_type": {
                "type": "string",
                "description": "General ledger that recorded the deposit."
              },
              "external_journal_entry_id": {
                "type": "string",
                "description": "Journal ID in the general ledger."
              },
              "external_journal_number": {
                "type": "string",
                "description": "Journal number in the general ledger."
              },
              "reason": {
                "type": "string",
                "description": "Why the deposit is not a customer payment."
              },
              "resolved_at": {
                "type": ["string", "null"],
                "format": "date-time",
                "description": "Time of the resolution."
              },
              "resolved_by": {
                "type": ["string", "null"],
                "description": "User who resolved the deposit."
              }
            }
          },
          "etag": {
            "type": "string",
            "readOnly": true,
            "pattern": "^\"[^\"\\r\\n]+\"$",
            "description": "Strong version of this resource. Send this value, including its quotes, in If-Match when updating it.",
            "examples": ["\"v_example\""]
          }
        }
      },
      "V1CashApplicationAllocation": {
        "type": "object",
        "required": ["target_type", "amount"],
        "properties": {
          "target_type": {
            "type": "string",
            "enum": ["invoice"],
            "description": "Always `invoice`."
          },
          "target_id": {
            "type": ["string", "null"],
            "description": "Invoice ID (`inv_…`), or `null` for a proposed allocation."
          },
          "invoice_number": {
            "type": ["string", "null"],
            "description": "Invoice number."
          },
          "amount": {
            "type": "string",
            "description": "Decimal string."
          },
          "customer_name": {
            "type": ["string", "null"],
            "description": "Customer name."
          }
        }
      },
      "V1ExternalAccount": {
        "type": "object",
        "required": ["external_id", "name"],
        "description": "An account in the general ledger. Use `external_id` to identify it.",
        "properties": {
          "external_id": {
            "type": "string",
            "description": "Account ID in the general ledger."
          },
          "name": {
            "type": "string",
            "description": "Account name in the general ledger."
          },
          "account_number": {
            "type": ["string", "null"],
            "description": "Account number in the general ledger."
          },
          "parent_account": {
            "type": ["string", "null"],
            "description": "Parent account in the general ledger."
          },
          "description": {
            "type": ["string", "null"],
            "description": "Account description."
          },
          "account_type": {
            "type": ["string", "null"],
            "description": "Account type, such as Bank, Expense or Credit Card."
          },
          "classification": {
            "type": ["string", "null"],
            "description": "Account classification in the general ledger."
          },
          "integration_type": {
            "type": ["string", "null"],
            "description": "General-ledger provider."
          },
          "eliminate": {
            "type": "boolean",
            "description": "`true` when the account is used for intercompany eliminations."
          },
          "realm_id": {
            "type": "string",
            "description": "Company ID in the general ledger."
          },
          "account_sub_type": {
            "type": ["string", "null"],
            "description": "Account subtype in the general ledger."
          },
          "ledger_account_sequence": {
            "type": ["string", "null"],
            "description": "Number of the mapped Entendre ledger account."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was last updated (ISO 8601)."
          }
        }
      },
      "V1ExternalEntity": {
        "type": "object",
        "required": ["external_id", "entity_name"],
        "properties": {
          "external_id": {
            "type": "string",
            "description": "Account ID in the general ledger."
          },
          "entity_name": {
            "type": "string",
            "description": "Entity name in the general ledger."
          },
          "address": {
            "type": ["string", "null"],
            "description": "Entity address."
          },
          "currency": {
            "type": ["string", "null"],
            "description": "Entity currency."
          },
          "integration_type": {
            "type": ["string", "null"],
            "description": "General-ledger provider."
          },
          "realm_id": {
            "type": "string",
            "description": "Company ID in the general ledger."
          },
          "entity_type": {
            "type": ["string", "null"],
            "description": "Entity type in the general ledger."
          },
          "status": {
            "type": ["string", "null"],
            "description": "Entity status in the general ledger."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the record was last updated (ISO 8601)."
          }
        }
      },
      "V1FinancialInsightMeta": {
        "type": "object",
        "required": ["source", "granularity", "start_date", "end_date", "currency"],
        "properties": {
          "source": {
            "type": "string",
            "enum": ["gl", "transactions"],
            "description": "Data source: `gl` for `basis=ledger`, `transactions` for `basis=transactions`."
          },
          "granularity": {
            "type": "string",
            "enum": ["daily", "weekly", "monthly"],
            "description": "Bucket size."
          },
          "start_date": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the window."
          },
          "end_date": {
            "type": "string",
            "format": "date-time",
            "description": "End of the window."
          },
          "currency": {
            "type": "string",
            "example": "USD",
            "description": "Currency of the amounts."
          },
          "granularity_note": {
            "type": ["string", "null"],
            "description": "Note when the bucket size differs from the request."
          },
          "period_snapped_note": {
            "type": ["string", "null"],
            "description": "Present when `basis=ledger` and the window is not whole months. The totals then cover the full accounting periods."
          },
          "account_ids_ignored": {
            "type": ["boolean", "null"],
            "description": "`true` when `account_ids` was ignored."
          },
          "account_ids_ignored_reason": {
            "type": ["string", "null"],
            "description": "Why `account_ids` was ignored."
          },
          "basis": {
            "type": "string",
            "enum": ["cash", "accrual"],
            "description": "Accounting basis of the figures: cash (basis=transactions, settled cash movements) or accrual (basis=ledger, the posted double-entry ledger)."
          },
          "cash_basis_caveat": {
            "type": ["string", "null"],
            "description": "Present when `basis=transactions`. Expenses do not include unpaid bills, accruals or non-cash journals."
          }
        }
      },
      "V1FinancialInsightSeriesPoint": {
        "type": "object",
        "required": ["period_start", "period_end", "amount"],
        "description": "One bucket of a single-amount financial-insight time series (used by revenue `time_series` and burn-rate `trend`). Monetary amounts are decimal strings.",
        "properties": {
          "period_start": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the bucket."
          },
          "period_end": {
            "type": "string",
            "format": "date-time",
            "description": "End of the bucket."
          },
          "amount": {
            "type": "string",
            "description": "Decimal-string amount for the bucket (revenue: income; burn-rate: expenses)."
          }
        }
      },
      "V1FinancialInsightSpendingEntry": {
        "type": "object",
        "required": ["key", "amount"],
        "description": "A keyed spending total (by source type or classification). `amount` is a decimal string.",
        "properties": {
          "key": {
            "type": "string",
            "description": "Source type or transaction type."
          },
          "amount": {
            "type": "string",
            "description": "Spending total (decimal string)."
          }
        }
      },
      "ValueFiat": {
        "type": "object",
        "description": "Fiat values as decimal strings: `gross` is quantity × unit price, `fee` is token fee × unit price, and `net` is gross − fee.",
        "required": ["gross", "net", "currency"],
        "properties": {
          "gross": {
            "type": "string",
            "description": "Total fiat value before fees (`quantity × unit price`). Used as the line amount for journal entries."
          },
          "fee": {
            "type": "string",
            "description": "Fee in fiat terms (`token fee × unit price`). `\"0.00\"` if no fee. When non-zero, the fee is typically posted as a separate FEE-classified transaction."
          },
          "net": {
            "type": "string",
            "description": "Fiat value after fees (`gross − fee`)."
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code (such as `USD`, `EUR`)."
          }
        }
      },
      "VaultDocument": {
        "type": "object",
        "description": "A document. `id` is `doc_<uuid>`.",
        "properties": {
          "id": {
            "type": "string",
            "example": "doc_b1d4f6e0",
            "description": "Document ID (`doc_…`)."
          },
          "organization_id": {
            "type": "string",
            "example": "org_123",
            "description": "Organization ID (`org_…`)."
          },
          "document_type": {
            "type": "string",
            "enum": ["bill", "receipt", "statement", "other"],
            "description": "Document type. Stored types other than bill, receipt and statement are returned as `other`."
          },
          "document_source": {
            "type": "string",
            "description": "How the document was added, such as upload or email."
          },
          "file_directory": {
            "type": ["string", "null"],
            "description": "Folder of the document."
          },
          "file_size": {
            "type": "integer",
            "description": "File size in bytes."
          },
          "filename": {
            "type": "string",
            "description": "Display filename. Renaming changes the name only, not the stored file."
          },
          "original_filename": {
            "type": ["string", "null"],
            "description": "File name at upload."
          },
          "file_extension": {
            "type": "string",
            "description": "File extension, such as `pdf`."
          },
          "summary": {
            "type": ["string", "null"],
            "description": "Summary of the document content."
          },
          "hash_sum": {
            "type": ["string", "null"],
            "description": "Hash of the file content."
          },
          "confidence_level": {
            "type": ["number", "null"],
            "description": "Confidence of the document classification, from 0 to 1."
          },
          "language": {
            "type": ["string", "null"],
            "description": "Document language."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the document was created (ISO 8601)."
          },
          "deleted_at": {
            "type": ["string", "null"],
            "description": "Time the document was deleted, or `null`."
          },
          "signed_url": {
            "type": "string",
            "description": "Short-lived URL to display the document inline, when permitted. Use download_url to save it."
          },
          "download_url": {
            "type": "string",
            "description": "Short-lived URL to download the document as an attachment, when permitted. signed_url_expires_at applies to both URLs."
          },
          "signed_url_expires_at": {
            "type": "string",
            "description": "Expiry time for signed_url and download_url.",
            "format": "date-time"
          }
        },
        "required": ["id", "organization_id", "document_type", "filename"]
      },
      "Warning": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable warning code."
          },
          "message": {
            "type": "string",
            "description": "Actionable explanation."
          },
          "field": {
            "type": ["string", "null"],
            "description": "Affected field, if known."
          }
        },
        "required": ["code", "message"],
        "additionalProperties": false
      },
      "AccountingImport": {
        "type": "object",
        "description": "The latest accounting import attempt for a connection. Starting another import replaces the previous status; individual run history is not available.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID of the general-ledger configuration (`glc_…`) for this import.",
            "example": "glc_507f1f77bcf86cd799439011"
          },
          "status": {
            "type": "string",
            "enum": ["pending", "in_progress", "completed", "failed"],
            "description": "Import status."
          },
          "progress": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Progress, in percent."
          },
          "message": {
            "type": ["string", "null"],
            "description": "Status message."
          },
          "error_message": {
            "type": ["string", "null"],
            "description": "Why the import failed, or `null`."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the import was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the import was last updated (ISO 8601)."
          },
          "completed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the import finished."
          }
        },
        "required": [
          "id",
          "status",
          "progress",
          "message",
          "error_message",
          "created_at",
          "updated_at",
          "completed_at"
        ],
        "additionalProperties": false
      },
      "WorkItem": {
        "type": "object",
        "properties": {
          "input_id": {
            "type": "string",
            "description": "Original row, transaction or journal ID."
          },
          "status": {
            "type": "string",
            "description": "Item outcome.",
            "enum": ["pending", "succeeded", "failed", "skipped"]
          },
          "resource_id": {
            "type": ["string", "null"],
            "description": "Created or matched ID."
          },
          "external_id": {
            "type": ["string", "null"],
            "description": "Provider result ID."
          },
          "code": {
            "type": ["string", "null"],
            "description": "Stable outcome code."
          },
          "message": {
            "type": ["string", "null"],
            "description": "Human-readable detail."
          }
        },
        "required": ["input_id", "status", "resource_id", "external_id", "code", "message"],
        "additionalProperties": false
      },
      "MemoryFrontmatter": {
        "type": ["object", "null"],
        "additionalProperties": true,
        "description": "Parsed frontmatter of the stored document, or null when it has none."
      },
      "MemoryDocument": {
        "type": "object",
        "required": ["path"],
        "properties": {
          "path": {
            "type": "string",
            "description": "Relative memory path."
          },
          "layer": {
            "type": "string",
            "enum": ["org", "firm", "default"],
            "description": "Which layer answered. Entendre reads the organization file, then the firm file, then the default. The first match wins, and files are never merged."
          },
          "version": {
            "type": ["string", "null"],
            "description": "Version of the returned layer. Send it as `expected_version` to replace an organization file."
          },
          "content": {
            "type": ["string", "null"],
            "description": "File body. Null when the document is suppressed. Omitted from directory manifests."
          },
          "frontmatter": {
            "$ref": "#/components/schemas/MemoryFrontmatter"
          },
          "missing": {
            "type": "boolean",
            "description": "The named path resolved to nothing in any layer."
          },
          "suppressed": {
            "type": "boolean",
            "description": "`true` when the organization hides the firm file for this path."
          },
          "unreadable": {
            "type": "string",
            "description": "Present when the file was skipped because its header did not parse. The reason is the value."
          }
        }
      },
      "MemoryReadResult": {
        "type": "object",
        "required": ["success", "documents", "truncated", "next_cursor"],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "`true` when the request succeeded."
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemoryDocument"
            },
            "description": "Documents in the directory."
          },
          "truncated": {
            "type": "boolean",
            "description": "Some documents were left out because the response was too large. Truncation does not show that a document is absent or that another page follows."
          },
          "next_cursor": {
            "type": ["string", "null"],
            "description": "Pass as `cursor` with the same filters to continue. Null when the listing is complete."
          }
        }
      },
      "MemorySearchMatch": {
        "type": "object",
        "required": ["path", "layer", "line", "text"],
        "properties": {
          "path": {
            "type": "string",
            "description": "Relative file path."
          },
          "layer": {
            "type": "string",
            "enum": ["org", "firm", "default"],
            "description": "Layer of the file: `org`, `firm` or `default`."
          },
          "line": {
            "type": "integer",
            "description": "1-based line number of the match."
          },
          "text": {
            "type": "string",
            "description": "The matching line. In a `policy/*.json` file, the text is the whole record."
          },
          "frontmatter": {
            "$ref": "#/components/schemas/MemoryFrontmatter"
          }
        }
      },
      "MemorySearchResult": {
        "type": "object",
        "required": ["success", "matches", "match_count", "truncated", "next_cursor"],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "`true` when the request succeeded."
          },
          "matches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemorySearchMatch"
            },
            "description": "Matching lines."
          },
          "match_count": {
            "type": "integer",
            "description": "Total matches found, which can exceed the number returned."
          },
          "truncated": {
            "type": "boolean",
            "description": "Some results were left out. Truncation does not show that a match is absent."
          },
          "other_number": {
            "type": "array",
            "description": "Present when `match_count` is 0: lines that match the singular or plural form of the query.",
            "items": {
              "type": "object",
              "required": ["path", "layer", "form", "line", "text"],
              "properties": {
                "path": {
                  "type": "string",
                  "description": "Relative file path."
                },
                "layer": {
                  "type": "string",
                  "enum": ["org", "firm", "default"],
                  "description": "Layer of the file: `org`, `firm` or `default`."
                },
                "form": {
                  "type": "string",
                  "description": "The inflected form that matched."
                },
                "line": {
                  "type": "integer",
                  "description": "Line number, starting at 1."
                },
                "text": {
                  "type": "string",
                  "description": "The matching line."
                }
              }
            }
          },
          "unreadable": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Paths skipped because their header did not parse."
          },
          "next_cursor": {
            "type": ["string", "null"],
            "description": "Pass as `cursor` with the same query and filters to continue."
          }
        }
      },
      "MemoryWriteResult": {
        "type": "object",
        "required": ["success", "path", "layer", "rationale"],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "`true` when the file was saved."
          },
          "path": {
            "type": "string",
            "description": "Relative file path."
          },
          "layer": {
            "type": "string",
            "enum": ["org"],
            "description": "The layer written. This endpoint writes organization scope only."
          },
          "rationale": {
            "type": "string",
            "description": "The rationale recorded with the write."
          }
        }
      },
      "MemoryDeleteResult": {
        "type": "object",
        "required": ["deleted", "path", "purged"],
        "properties": {
          "deleted": {
            "type": "boolean",
            "description": "`true` when the file was deleted."
          },
          "path": {
            "type": "string",
            "description": "Relative file path."
          },
          "purged": {
            "type": "boolean",
            "description": "True when the file was removed permanently rather than moved to .trash/."
          },
          "trash_path": {
            "type": "string",
            "description": "Where a soft-deleted file now lives. Absent on a purge."
          }
        }
      },
      "MemoryErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "request_id"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code."
              },
              "message": {
                "type": "string",
                "description": "Technical description for developers."
              },
              "fields": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Present only on VALIDATION_ERROR. Maps failing field paths to reason strings."
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "Extra error details for agent operations. The keys can differ from the public field names; use them for diagnosis only."
              },
              "suggested_action": {
                "type": "string",
                "description": "A suggested next step."
              },
              "documentation_url": {
                "type": "string",
                "format": "uri",
                "description": "Link to documentation about this error."
              },
              "request_id": {
                "type": "string",
                "description": "Unique request ID for support escalation."
              }
            },
            "description": "Error details."
          }
        }
      },
      "VaultVendor": {
        "type": "object",
        "description": "A vendor. `id` is `vnd_<uuid>`. List responses add `files_count` and `total_bills_amount`.",
        "properties": {
          "id": {
            "type": "string",
            "example": "vnd_abc123",
            "description": "Vendor ID (`vnd_…`)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "name": {
            "type": "string",
            "description": "Vendor name."
          },
          "website_url": {
            "type": ["string", "null"],
            "description": "Vendor website."
          },
          "is_ramp_managed": {
            "type": "boolean",
            "description": "`true` when Ramp manages the vendor."
          },
          "is_ap_vendor": {
            "type": "boolean",
            "description": "`true` for an accounts-payable vendor."
          },
          "default_gl_account": {
            "type": ["string", "null"],
            "description": "Default account in the general ledger."
          },
          "payment_terms": {
            "type": ["string", "null"],
            "description": "Payment terms."
          },
          "external_vendor_id": {
            "type": ["string", "null"],
            "description": "Vendor ID in the general ledger."
          },
          "gl_type": {
            "type": ["string", "null"],
            "description": "General-ledger provider."
          },
          "realm_id": {
            "type": ["string", "null"],
            "description": "Company ID in the general ledger."
          },
          "default_expense_account_id": {
            "type": ["string", "null"],
            "description": "Default expense ledger account (`lac_…`)."
          },
          "last_gl_sync": {
            "type": ["string", "null"],
            "description": "Last sync with the general ledger."
          },
          "gl_sync_status": {
            "type": ["string", "null"],
            "description": "Sync status with the general ledger."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the vendor was created (ISO 8601)."
          },
          "files_count": {
            "type": "integer",
            "description": "In list responses only."
          },
          "total_bills_amount": {
            "type": ["string", "null"],
            "description": "Total of the vendor bills (decimal string). In list responses only."
          }
        }
      },
      "RealizedGainsCurrencyBlock": {
        "type": "object",
        "required": [
          "currency",
          "total_proceeds",
          "total_cost_basis",
          "total_gain",
          "short_term_gain",
          "long_term_gain",
          "disposal_count",
          "sold_asset_count"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO 4217 fiat currency these totals are denominated in (from the lots' own records)."
          },
          "total_proceeds": {
            "type": "string",
            "description": "Sum of proceeds from this currency's disposals (decimal string)."
          },
          "total_cost_basis": {
            "type": "string",
            "description": "Sum of cost basis for this currency's disposals (decimal string)."
          },
          "total_gain": {
            "type": "string",
            "description": "Net gain or loss in this currency. Negative values indicate a net loss (decimal string)."
          },
          "short_term_gain": {
            "type": "string",
            "description": "Gain/loss from assets held 1 year or less (decimal string)."
          },
          "long_term_gain": {
            "type": "string",
            "description": "Gain/loss from assets held more than 1 year (365.25-day boundary) (decimal string)."
          },
          "disposal_count": {
            "type": "integer",
            "description": "Disposal events in this currency."
          },
          "sold_asset_count": {
            "type": "integer",
            "description": "Sold asset lots in this currency."
          }
        }
      },
      "RealizedGainsSummary": {
        "type": "object",
        "description": "Present when `summary=true`. Totals cover all pages. Flat totals appear only for a single currency.",
        "required": ["methodology", "by_currency", "disposal_count", "sold_asset_count"],
        "properties": {
          "methodology": {
            "type": "string",
            "description": "Always `per_unit_cost_basis_approximation`: (sale price − cost basis) × quantity sold, for each disposal."
          },
          "by_currency": {
            "type": "array",
            "description": "Totals for each lot currency, sorted by currency code. Currencies are not combined.",
            "items": {
              "$ref": "#/components/schemas/RealizedGainsCurrencyBlock"
            }
          },
          "disposal_count": {
            "type": "integer",
            "description": "Total number of disposal events in the period, across all currencies (counts are currency-independent)."
          },
          "sold_asset_count": {
            "type": "integer",
            "description": "Number of sold asset lots aggregated across all currencies (the rows the paginated report would return)."
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 fiat currency of the flat totals. Present only when the whole scope is single-currency."
          },
          "total_proceeds": {
            "type": "string",
            "description": "Sum of proceeds from all disposals (decimal string). Present only when single-currency."
          },
          "total_cost_basis": {
            "type": "string",
            "description": "Sum of cost basis for all disposals (decimal string). Present only when single-currency."
          },
          "total_gain": {
            "type": "string",
            "description": "Net gain or loss. Negative values indicate a net loss (decimal string). Present only when single-currency."
          },
          "short_term_gain": {
            "type": "string",
            "description": "Gain/loss from assets held 1 year or less (decimal string). Present only when single-currency."
          },
          "long_term_gain": {
            "type": "string",
            "description": "Gain/loss from assets held more than 1 year (365.25-day boundary) (decimal string). Present only when single-currency."
          }
        }
      },
      "V1FinancialInsightCategoryAmount": {
        "type": "object",
        "required": ["category", "amount"],
        "description": "A named category total. `amount` is a decimal string.",
        "properties": {
          "category": {
            "type": "string",
            "description": "Category name."
          },
          "amount": {
            "type": "string",
            "description": "Category total (decimal string)."
          }
        }
      },
      "SourceImport": {
        "type": "object",
        "description": "Confirms that a transaction import is queued for one source. `status` is `queued`; it does not show completion. No operation reports the import progress.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Import job ID (`job_…`).",
            "example": "job_wallet-sync:realtime:507f1f77bcf86cd799439011"
          },
          "source_id": {
            "type": "string",
            "nullable": true,
            "description": "Prefixed id of the source this import runs against."
          },
          "status": {
            "type": "string",
            "enum": ["queued"],
            "description": "Always `queued`."
          }
        },
        "required": ["id", "source_id", "status"],
        "additionalProperties": false
      },
      "JournalSync": {
        "type": "object",
        "description": "One general-ledger sync run: an accounting period's worth of journals pushed to one provider. A single Sync journals request can produce several runs.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Sync run ID.",
            "example": "sh_507f1f77bcf86cd799439011"
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Owning organization."
          },
          "accounting_period_id": {
            "type": ["string", "null"],
            "description": "Accounting period the run covered."
          },
          "created_by": {
            "type": ["string", "null"],
            "description": "User who started the run. Null when system-initiated."
          },
          "integration_type": {
            "type": "string",
            "description": "Destination general-ledger provider.",
            "enum": ["quickbooks", "xero", "netsuite", "dualentry", "campfire"]
          },
          "job_status": {
            "type": ["string", "null"],
            "description": "Run status. `null` for older runs whose status cannot be read; count them as unknown, not as successes.",
            "enum": ["started", "in_progress", "completed", "job_failed", "canceled", "hanged", null]
          },
          "synced_count": {
            "type": ["integer", "null"],
            "description": "Journals the provider accepted."
          },
          "failed_count": {
            "type": ["integer", "null"],
            "description": "Journals the provider rejected."
          },
          "total_count": {
            "type": ["integer", "null"],
            "description": "Journals selected for the run."
          },
          "completed_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the job finished (ISO 8601)."
          },
          "error_message": {
            "type": ["string", "null"],
            "description": "Failure reason when the whole run failed."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "ISO 8601 UTC timestamp."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "ISO 8601 UTC timestamp."
          }
        },
        "required": [
          "id",
          "organization_id",
          "accounting_period_id",
          "created_by",
          "integration_type",
          "job_status",
          "synced_count",
          "failed_count",
          "total_count",
          "completed_at",
          "error_message",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "BankCashBalance": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Bank account ID."
          },
          "current": {
            "type": ["string", "null"],
            "description": "Current balance (decimal string)."
          },
          "available": {
            "type": ["string", "null"],
            "description": "Available balance (decimal string)."
          },
          "currency": {
            "type": ["string", "null"],
            "description": "Account currency."
          },
          "usdValue": {
            "type": ["string", "null"],
            "description": "Current balance in USD (decimal string)."
          },
          "providerUpdatedAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the bank last updated the balance."
          },
          "retrievedAt": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time Entendre read the balance."
          },
          "connectionStatus": {
            "type": ["string", "null"],
            "description": "Status of the bank connection."
          },
          "valuationGap": {
            "type": ["string", "null"],
            "enum": ["balance_unavailable", "currency_unavailable", "fx_unavailable", "connection_unavailable", null],
            "description": "Why the USD value is missing, or `null`."
          }
        },
        "required": [
          "accountId",
          "current",
          "available",
          "currency",
          "usdValue",
          "providerUpdatedAt",
          "retrievedAt",
          "connectionStatus",
          "valuationGap"
        ],
        "additionalProperties": false
      },
      "OperationalRule": {
        "type": "object",
        "required": ["rule_id", "domain", "title", "statement", "created_at"],
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Rule ID (such as `rule_ab12cd34`). Pass it as `rule_id` to Delete memory with `kind=rule`."
          },
          "domain": {
            "type": "string",
            "enum": ["classification", "cash_application"],
            "description": "Rule type: `classification` (transaction categorization) or `cash_application` (invoice/deposit matching)."
          },
          "title": {
            "type": "string",
            "description": "Short human-readable rule name."
          },
          "statement": {
            "type": "string",
            "description": "Human-readable summary of what the rule matches and where it routes."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Time the rule was created (ISO 8601)."
          },
          "action": {
            "type": "string",
            "enum": ["route_to_account", "require_human_review"],
            "description": "For cash-application rules: what the rule does when its matcher fires."
          },
          "matcher": {
            "type": "string",
            "description": "For cash-application rules: the verbatim matcher phrase compared against invoice line text."
          },
          "match_operator": {
            "type": "string",
            "enum": ["exact", "contains"],
            "description": "For cash-application rules: how `matcher` is compared (`contains` fires on any occurrence; `exact` requires the normalized line label to equal it)."
          },
          "normalized_matcher": {
            "type": "string",
            "description": "For cash-application rules: the matcher as Entendre compares it, in lowercase and without punctuation."
          },
          "ledger_account_id": {
            "type": "string",
            "description": "For cash-application rules with route_to_account: target ledger account."
          },
          "ledger_account_name": {
            "type": "string",
            "description": "Name of the target ledger account."
          },
          "ledger_account_archived": {
            "type": "boolean",
            "description": "Present and `true` only when the target ledger account is archived. The rule still routes to it, so change or delete the rule."
          },
          "description_contains": {
            "type": "string",
            "description": "Classification rules: text that matches the memo or payee. Returned in lowercase."
          },
          "source_category": {
            "type": "string",
            "description": "For classification rules: source-platform category matched."
          },
          "merchant_name": {
            "type": "string",
            "description": "For classification rules: merchant name matched."
          },
          "blockchain_address": {
            "type": "string",
            "description": "Classification rules: address that matches the from or to address. Returned in lowercase."
          },
          "asset_type": {
            "type": "string",
            "description": "For classification rules: asset symbol matched."
          },
          "direction": {
            "type": "string",
            "enum": ["DEPOSIT", "WITHDRAWAL", "ANY"],
            "description": "For classification rules: transaction direction constraint."
          },
          "category_ledger_account_id": {
            "type": "string",
            "description": "For classification rules: prefixed target ledger account id."
          },
          "category_ledger_account_name": {
            "type": "string",
            "description": "For classification rules: target ledger account name."
          },
          "category_ledger_account_archived": {
            "type": "boolean",
            "description": "For classification rules: present and true only when the category target ledger account is archived. Change or delete the rule."
          },
          "category_ledger_account_sequence": {
            "type": ["integer", "null"],
            "description": "For classification rules: target ledger account sequence."
          },
          "resolved_payee": {
            "type": "string",
            "description": "For classification rules: clean payee applied by the rule."
          },
          "default_tag_id": {
            "type": "string",
            "description": "For classification rules: prefixed tag applied by the rule."
          }
        }
      },
      "V1CashApplicationInvoice": {
        "type": "object",
        "description": "A Stripe invoice, with its cash-application eligibility.",
        "required": [
          "id",
          "invoice_number",
          "customer_name",
          "customer_id",
          "amount_due",
          "currency",
          "legal_entity_id",
          "transaction_id",
          "provider",
          "eligible",
          "ineligibility_reason"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Invoice ID (`inv_…`).",
            "example": "inv_507f1f77bcf86cd799439011"
          },
          "invoice_number": {
            "type": ["string", "null"],
            "description": "Provider invoice number."
          },
          "customer_name": {
            "type": ["string", "null"],
            "description": "Customer name."
          },
          "customer_id": {
            "type": ["string", "null"],
            "description": "Stripe customer id (provider reference)."
          },
          "status": {
            "type": ["string", "null"],
            "description": "Stripe invoice status: `draft`, `open`, `paid`, `uncollectible`, or `void`."
          },
          "amount_due": {
            "type": "string",
            "description": "Decimal string; parse with a decimal library, not binary floating point.",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "total_amount": {
            "type": "string",
            "description": "Invoice total (decimal string).",
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "example": "100.00"
          },
          "invoice_date": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Invoice issue date (ISO 8601)."
          },
          "due_date": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Invoice due date (ISO 8601)."
          },
          "currency": {
            "type": "string",
            "example": "USD",
            "description": "Invoice currency."
          },
          "legal_entity_id": {
            "type": ["string", "null"],
            "description": "Always `null`: invoices are not linked to a legal entity."
          },
          "transaction_id": {
            "type": ["string", "null"],
            "description": "Transaction ID (`txn_…`) of the linked deposit, when one exists."
          },
          "provider": {
            "type": "string",
            "enum": ["stripe"],
            "description": "Always `stripe`."
          },
          "eligible": {
            "type": "boolean",
            "description": "True only while the invoice is `open` with a positive `amount_due`."
          },
          "ineligibility_reason": {
            "type": ["string", "null"],
            "enum": ["paid", "void", "draft", "uncollectible", "zero_amount_due", null],
            "description": "Set when `eligible` is false."
          }
        }
      },
      "V1GLConnectXero": {
        "type": "object",
        "title": "Xero (OAuth)",
        "required": ["provider"],
        "properties": {
          "provider": {
            "type": "string",
            "enum": ["xero"],
            "description": "Always `xero`."
          },
          "redirect_url": {
            "type": "string",
            "format": "uri",
            "description": "Where the OAuth flow should return after consent. Either redirect_url or subdomain is required."
          },
          "subdomain": {
            "type": "string",
            "description": "Your Entendre subdomain. Either redirect_url or subdomain is required."
          },
          "legal_entity_id": {
            "type": "string",
            "nullable": true,
            "description": "Legal entity to connect (`le_…`)."
          }
        }
      },
      "V1GLConnectNetSuite": {
        "type": "object",
        "title": "NetSuite (OAuth)",
        "required": ["provider"],
        "properties": {
          "provider": {
            "type": "string",
            "enum": ["netsuite"],
            "description": "Always `netsuite`."
          },
          "redirect_url": {
            "type": "string",
            "format": "uri",
            "description": "Where the OAuth flow should return after consent. Either redirect_url or subdomain is required."
          },
          "subdomain": {
            "type": "string",
            "description": "Your Entendre subdomain. Either redirect_url or subdomain is required."
          },
          "legal_entity_id": {
            "type": "string",
            "nullable": true,
            "description": "Legal entity to connect (`le_…`)."
          },
          "account_id": {
            "type": "string",
            "description": "Ignored. NetSuite authorization applies to the whole organization, and NetSuite must be set up for your organization first."
          }
        }
      },
      "V1GLConnectQuickBooks": {
        "type": "object",
        "title": "QuickBooks (OAuth)",
        "required": ["provider"],
        "properties": {
          "provider": {
            "type": "string",
            "enum": ["quickbooks"],
            "description": "Always `quickbooks`."
          },
          "redirect_url": {
            "type": "string",
            "format": "uri",
            "description": "Where the OAuth flow should return after consent. Either redirect_url or subdomain is required."
          },
          "subdomain": {
            "type": "string",
            "description": "Your Entendre subdomain. Either redirect_url or subdomain is required."
          },
          "legal_entity_id": {
            "type": "string",
            "nullable": true,
            "description": "Legal entity to connect (`le_…`)."
          }
        }
      },
      "V1GLConnectCampfire": {
        "type": "object",
        "title": "Campfire (API key)",
        "required": ["provider", "api_key"],
        "properties": {
          "provider": {
            "type": "string",
            "enum": ["campfire"],
            "description": "Always `campfire`."
          },
          "api_key": {
            "type": "string",
            "description": "Provider API key. Validated against the provider, then encrypted at rest."
          }
        }
      },
      "V1GLConnectDualEntry": {
        "type": "object",
        "title": "DualEntry (API key)",
        "required": ["provider", "api_key"],
        "properties": {
          "provider": {
            "type": "string",
            "enum": ["dualentry"],
            "description": "Always `dualentry`."
          },
          "api_key": {
            "type": "string",
            "description": "Provider API key. Validated against the provider, then encrypted at rest."
          }
        }
      },
      "V1SourceGroup": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Prefixed `sgp_` id."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Prefixed `org_` id."
          },
          "name": {
            "type": ["string", "null"],
            "description": "Group name."
          },
          "icon": {
            "type": ["string", "null"],
            "description": "Group icon."
          },
          "emoji": {
            "type": ["string", "null"],
            "description": "Group emoji."
          },
          "reference_wallet_id": {
            "type": ["string", "null"],
            "description": "Wallet (`wal_…`) linked to the group, if any."
          },
          "created_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the source group was created (ISO 8601)."
          },
          "updated_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Time the source group was last updated (ISO 8601)."
          }
        }
      },
      "ClassificationJob": {
        "type": "object",
        "additionalProperties": false,
        "required": ["job_id", "status", "type"],
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Classification id (`cls_…`). Use it with Get classification status."
          },
          "status": {
            "type": "string",
            "enum": ["queued"],
            "description": "Always `queued` on acceptance."
          },
          "type": {
            "type": "string",
            "enum": ["classification"],
            "description": "Always `classification`."
          }
        }
      },
      "VaultBill": {
        "type": "object",
        "description": "A bill. `id` is `bil_<uuid>`; amounts are 2-place decimal strings.",
        "properties": {
          "id": {
            "type": "string",
            "example": "bil_abc123",
            "description": "Bill ID (`bil_…`)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "document_id": {
            "type": ["string", "null"],
            "description": "Document ID (`doc_…`)."
          },
          "vendor_id": {
            "type": ["string", "null"],
            "description": "Vendor ID (`vnd_…`)."
          },
          "bill_number": {
            "type": ["string", "null"],
            "description": "Bill number."
          },
          "bill_date": {
            "type": ["string", "null"],
            "description": "Bill date."
          },
          "due_date": {
            "type": ["string", "null"],
            "description": "Due date."
          },
          "billing_period_start": {
            "type": ["string", "null"],
            "description": "Start of the billing period."
          },
          "billing_period_end": {
            "type": ["string", "null"],
            "description": "End of the billing period."
          },
          "currency": {
            "type": ["string", "null"],
            "description": "Bill currency."
          },
          "total_amount": {
            "type": ["string", "null"],
            "description": "Bill total (decimal string)."
          },
          "tax_amount": {
            "type": ["string", "null"],
            "description": "Tax amount (decimal string)."
          },
          "tax_rate": {
            "type": ["string", "null"],
            "description": "Tax rate."
          },
          "tax_type": {
            "type": ["string", "null"],
            "description": "Tax type, such as VAT."
          },
          "line_items": {
            "description": "Line items as extracted from the document."
          },
          "payment_instructions": {
            "description": "Payment instructions as extracted from the document."
          },
          "notes": {
            "type": ["string", "null"],
            "description": "Notes."
          },
          "external_bill_id": {
            "type": ["string", "null"],
            "description": "Bill ID in the external system."
          },
          "external_bill_source": {
            "type": ["string", "null"],
            "description": "External system of the bill."
          },
          "is_accrued": {
            "type": "boolean",
            "description": "`true` when the bill is accrued."
          },
          "gl_reference": {
            "type": ["string", "null"],
            "description": "Reference in the general ledger."
          },
          "gl_sync_status": {
            "type": ["string", "null"],
            "description": "Sync status with the general ledger."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the bill was created (ISO 8601)."
          }
        }
      },
      "VaultReceipt": {
        "type": "object",
        "description": "A receipt. `id` is `rct_<uuid>`.",
        "properties": {
          "id": {
            "type": "string",
            "example": "rct_abc123",
            "description": "Receipt ID (`rct_…`)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "document_id": {
            "type": ["string", "null"],
            "description": "Document ID (`doc_…`)."
          },
          "vendor_id": {
            "type": ["string", "null"],
            "description": "Vendor ID (`vnd_…`)."
          },
          "receipt_number": {
            "type": ["string", "null"],
            "description": "Receipt number."
          },
          "invoice_number": {
            "type": ["string", "null"],
            "description": "Invoice number on the receipt."
          },
          "receipt_date": {
            "type": ["string", "null"],
            "description": "Receipt date."
          },
          "currency": {
            "type": ["string", "null"],
            "description": "Receipt currency."
          },
          "total_amount": {
            "type": ["string", "null"],
            "description": "Receipt total (decimal string)."
          },
          "subtotal_amount": {
            "type": ["string", "null"],
            "description": "Total before tax (decimal string)."
          },
          "tax_amount": {
            "type": ["string", "null"],
            "description": "Tax amount (decimal string)."
          },
          "tax_rate": {
            "type": ["string", "null"],
            "description": "Tax rate."
          },
          "tax_type": {
            "type": ["string", "null"],
            "description": "Tax type, such as VAT."
          },
          "line_items": {
            "description": "Line items as extracted from the document."
          },
          "payment_method": {
            "type": ["string", "null"],
            "description": "Payment method."
          },
          "notes": {
            "type": ["string", "null"],
            "description": "Notes."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the receipt was created (ISO 8601)."
          }
        }
      },
      "VaultBankStatement": {
        "type": "object",
        "description": "A bank statement. `id` is `bnk_<uuid>`.",
        "properties": {
          "id": {
            "type": "string",
            "example": "bnk_abc123",
            "description": "Bank statement ID (`bnk_…`)."
          },
          "document_id": {
            "type": ["string", "null"],
            "description": "Document ID (`doc_…`)."
          },
          "organization_id": {
            "type": ["string", "null"],
            "description": "Organization ID (`org_…`)."
          },
          "bank_name": {
            "type": ["string", "null"],
            "description": "Bank name."
          },
          "account_number": {
            "type": ["string", "null"],
            "description": "Account number."
          },
          "account_number_last_four": {
            "type": ["string", "null"],
            "description": "Last four digits of the account number."
          },
          "account_name": {
            "type": ["string", "null"],
            "description": "Account name."
          },
          "linked_account_id": {
            "type": ["string", "null"],
            "description": "Source selected for statement imports, using the same public ID as the document source_id."
          },
          "statement_date": {
            "type": ["string", "null"],
            "description": "Statement date."
          },
          "period_start": {
            "type": ["string", "null"],
            "description": "Start of the statement period."
          },
          "period_end": {
            "type": ["string", "null"],
            "description": "End of the statement period."
          },
          "opening_balance": {
            "type": ["string", "null"],
            "description": "Opening balance (decimal string)."
          },
          "closing_balance": {
            "type": ["string", "null"],
            "description": "Closing balance (decimal string)."
          },
          "currency": {
            "type": "string",
            "description": "Statement currency."
          },
          "account_category": {
            "type": "string",
            "description": "Account category, such as bank or exchange."
          },
          "reconciliation_status": {
            "type": "string",
            "enum": ["not_reconciled", "reconciled"],
            "readOnly": true,
            "description": "Statement reconciliation state maintained by import and dashboard workflows. This is separate from import job completion."
          },
          "transactions_count": {
            "type": ["integer", "null"],
            "description": "Number of extracted lines."
          },
          "expected_transaction_count": {
            "type": ["integer", "null"],
            "description": "How many activity rows the source document prints, counted from the PDF itself rather than from the extraction. Null when no verdict could be reached."
          },
          "extraction_completeness": {
            "type": "string",
            "enum": ["complete", "incomplete", "unknown", "not_applicable"],
            "description": "Whether the extracted lines match the document. `not_applicable` for a file with nothing to check against, such as a CSV."
          },
          "extraction_completeness_detail": {
            "type": ["object", "null"],
            "description": "Counts of expected, missing and unexpected lines. The reason `legacy_pre_feature` means the check did not run.",
            "properties": {
              "reason": {
                "type": "string",
                "description": "Why completeness has its value."
              },
              "missing_count": {
                "type": ["integer", "null"],
                "description": "Lines in the document that were not extracted."
              },
              "unexpected_count": {
                "type": ["integer", "null"],
                "description": "Extracted lines that the document does not show."
              },
              "short_dates": {
                "type": ["array", "null"],
                "items": {
                  "type": "string"
                },
                "description": "Dates with fewer extracted lines than the document shows."
              },
              "repair_outcome": {
                "type": ["string", "null"],
                "description": "Result of the automatic repair, if one ran."
              }
            }
          },
          "reconciled_at": {
            "type": ["string", "null"],
            "readOnly": true,
            "description": "Recorded reconciliation timestamp, or null when none is recorded."
          },
          "reconciled_by": {
            "type": ["string", "null"],
            "readOnly": true,
            "description": "User ID recorded for reconciliation, or null when no user is recorded."
          },
          "notes": {
            "type": ["string", "null"],
            "description": "Notes."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the bank statement was created (ISO 8601)."
          },
          "lines": {
            "$ref": "#/components/schemas/StatementImportRows",
            "description": "Present only with `expand=statement.lines`. By default, an import takes only pending rows that are not invalid."
          }
        }
      },
      "StatementImportRow": {
        "type": "object",
        "additionalProperties": false,
        "description": "An extracted statement row for review or import selection. Not an imported transaction.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^bkl_[A-Za-z0-9-]+$",
            "description": "Statement line ID (`bkl_…`). Use it in `statement_line_ids`."
          },
          "statement_id": {
            "type": "string",
            "description": "Statement ID (`bnk_…`)."
          },
          "transaction_date": {
            "type": "string",
            "format": "date",
            "description": "Date of the line."
          },
          "description": {
            "type": ["string", "null"],
            "description": "Description on the statement."
          },
          "amount": {
            "type": ["string", "null"],
            "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$",
            "description": "Statement amount, not necessarily asset quantity. Null when extraction could not establish it."
          },
          "transaction_type": {
            "type": "string",
            "enum": ["debit", "credit"],
            "description": "`debit` or `credit`."
          },
          "validation_state": {
            "type": ["string", "null"],
            "description": "`invalid` rows cannot be imported. Null means no validation verdict was stored; it does not exclude the row.",
            "enum": ["valid", "invalid", null]
          },
          "validation_reasons": {
            "type": ["array", "null"],
            "items": {
              "type": "string"
            },
            "description": "Why the line is invalid."
          },
          "import_status": {
            "type": "string",
            "enum": ["pending", "imported", "ignored", "duplicate"],
            "description": "Import status of the line."
          },
          "imported_transaction_id": {
            "type": ["string", "null"],
            "description": "Created or matched transaction, when available."
          },
          "imported_sequence_number": {
            "type": ["string", "null"],
            "description": "Sequence number of the imported transaction."
          },
          "reconciliation_status": {
            "type": ["string", "null"],
            "description": "Stored row reconciliation state. Import completion does not prove statement completeness."
          },
          "reference_number": {
            "type": ["string", "null"],
            "description": "Reference number on the statement."
          },
          "category": {
            "type": ["string", "null"],
            "description": "Category on the statement."
          },
          "counterparty": {
            "type": ["string", "null"],
            "description": "Counterparty on the statement."
          },
          "imported_at": {
            "type": ["string", "null"],
            "description": "Time the line was imported."
          },
          "created_at": {
            "type": ["string", "null"],
            "description": "Time the statement line was created (ISO 8601)."
          },
          "is_reconciled": {
            "type": "boolean",
            "description": "`true` when the line is reconciled."
          }
        },
        "required": [
          "id",
          "statement_id",
          "transaction_date",
          "description",
          "amount",
          "transaction_type",
          "validation_state",
          "validation_reasons",
          "import_status",
          "imported_transaction_id",
          "imported_sequence_number",
          "reconciliation_status",
          "reference_number",
          "category",
          "counterparty",
          "imported_at",
          "created_at",
          "is_reconciled"
        ]
      },
      "StatementImportRows": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatementImportRow"
            },
            "description": "Lines on this page."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of lines that match the filters."
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether another page of lines is available."
          },
          "next_cursor": {
            "type": ["string", "null"],
            "description": "Pass as `statement_cursor` with the same `document_ids` and `expand`."
          }
        },
        "required": ["data", "count", "has_more", "next_cursor"]
      },
      "VaultDocumentEnvelope": {
        "type": "object",
        "description": "Returned for each document when `expand` names a related record. Each related key is `null` when the document has no linked record.",
        "properties": {
          "document": {
            "$ref": "#/components/schemas/VaultDocument"
          },
          "bill": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VaultBill"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present with `expand=bill`."
          },
          "receipt": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VaultReceipt"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present with `expand=receipt`."
          },
          "vendor": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VaultVendor"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present with `expand=vendor`."
          },
          "statement": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VaultBankStatement"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present with `expand=statement` or `expand=statement.lines`."
          }
        },
        "required": ["document"]
      }
    }
  }
}
