{
  "openapi": "3.1.0",
  "info": {
    "title": "Triqai Transaction Enrichment API",
    "version": "1.5.43",
    "description": "The Triqai API provides transaction enrichment capabilities for financial applications.\n\n## Authentication\n\nAll API endpoints require an API key in the `X-API-Key` header.\n\n## Rate Limiting\n\nPer-organization limits use a token bucket (RPS) plus a concurrent in-flight cap.\nHeaders may include:\n- `X-RateLimit-Limit`\n- `X-RateLimit-Remaining`\n- `X-RateLimit-Reset`\n- `X-RateLimit-Scope` (`rps` or `concurrency`)\n- `X-RateLimit-Concurrency-Limit`\n- `X-RateLimit-Concurrency-Remaining`\n\n`Retry-After` is returned in **seconds** on throttled responses.\n\n## Idempotency\n\nYou must supply `Idempotency-Key` (or `X-Idempotency-Key`) for enrichment requests so retries preserve billing and persistence identity.\nKeys must match `^[a-zA-Z0-9_-]{1,64}$`.\nReusing a key returns `409`:\n- `state=completed`: request with this key already finished\n- `state=in_progress`: request with this key is still processing (`Retry-After` included)\n",
    "contact": {
      "name": "Triqai Contact",
      "url": "https://triqai.com/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://triqai.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.triqai.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Health"
    },
    {
      "name": "API"
    },
    {
      "name": "Transactions"
    },
    {
      "name": "Categories"
    },
    {
      "name": "Entities"
    },
    {
      "name": "Issue Reports"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Root health check",
        "description": "Returns the same health payload as `/health`.",
        "operationId": "getRoot",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Health check",
        "operationId": "getHealth",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1": {
      "get": {
        "tags": [
          "API"
        ],
        "summary": "API info",
        "operationId": "getApiInfo",
        "responses": {
          "200": {
            "description": "API version and endpoint map",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiInfoResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/v1/transactions/enrich": {
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Enrich transaction",
        "description": "Enriches a transaction and returns structured transaction + entity data.",
        "operationId": "enrichTransaction",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required retry identity. `X-Idempotency-Key` is also accepted and must match when both are sent.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "pattern": "^[a-zA-Z0-9_-]{1,64}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnrichRequest"
              },
              "examples": {
                "expense": {
                  "summary": "Basic expense enrichment",
                  "value": {
                    "title": "AMAZON MKTPLACE PMTS AMZN.COM/BILL WA",
                    "country": "US",
                    "type": "expense"
                  }
                },
                "income": {
                  "summary": "Basic income enrichment",
                  "value": {
                    "title": "PAYPAL REFUND EBAY INC",
                    "country": "US",
                    "type": "income"
                  }
                },
                "with_prefilled_merchant": {
                  "summary": "Pre-fill known merchant to skip AI extraction",
                  "value": {
                    "title": "SQ *STARBUCKS #1234 AMSTERDAM",
                    "country": "NL",
                    "type": "expense",
                    "options": {
                      "merchant": {
                        "name": "Starbucks"
                      }
                    }
                  }
                },
                "with_prefilled_location": {
                  "summary": "Pre-fill known location context",
                  "value": {
                    "title": "SQ *STARBUCKS #1234 AMSTERDAM",
                    "country": "NL",
                    "type": "expense",
                    "options": {
                      "merchant": {
                        "name": "Starbucks"
                      },
                      "location": {
                        "cityName": "Amsterdam"
                      }
                    }
                  }
                },
                "with_filters": {
                  "summary": "Skip intermediary and location extraction",
                  "value": {
                    "title": "PAYPAL *NETFLIX.COM",
                    "country": "US",
                    "type": "expense",
                    "options": {
                      "filters": {
                        "noIntermediary": true,
                        "noLocation": true
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Enrichment completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnrichSuccessResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DuplicateRequest"
          },
          "410": {
            "description": "Transaction persistence refused because the transaction was erased or the organization is inactive. This response is terminal and must not be retried automatically.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "499": {
            "$ref": "#/components/responses/ClientDisconnected"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/GatewayTimeout"
          }
        }
      }
    },
    "/v1/transactions": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "List transactions",
        "operationId": "listTransactions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Inclusive lower bound (ISO 8601 timestamp)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "Inclusive upper bound (ISO 8601 timestamp)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated transactions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/transactions/{id}": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get transaction",
        "operationId": "getTransaction",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetailResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Delete transaction",
        "description": "Deletes the retained transaction and its temporary private data. If cleanup is\nincomplete, returns 503; retry the same request to continue cleanup.\n",
        "operationId": "deleteTransaction",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction deleted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteTransactionResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/transactions/count": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Count transactions",
        "description": "Returns the total number of transactions for the authenticated organization.\nOptionally filter by `afterDate` to count only transactions created on or after a given date.\n",
        "operationId": "countTransactions",
        "parameters": [
          {
            "name": "afterDate",
            "in": "query",
            "required": false,
            "description": "Only count transactions created on or after this ISO 8601 timestamp.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction count",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionCountResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/transactions/batch": {
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Batch delete transactions",
        "description": "Delete multiple transactions in a single request. Provide exactly **one** of:\n- `all: true` — delete every transaction for the organization\n- `afterDate` — delete all transactions created on or after the given ISO 8601 date\n- `ids` — delete specific transactions by UUID (max 1000)\n\nTemporary private data is purged after deletion. If cleanup is incomplete,\nreturns 503; retry the same request to continue cleanup, even if the\ntransaction records have already been deleted.\n",
        "operationId": "batchDeleteTransactions",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchDeleteRequest"
              },
              "examples": {
                "delete_all": {
                  "summary": "Delete all transactions",
                  "value": {
                    "all": true
                  }
                },
                "delete_by_date": {
                  "summary": "Delete transactions after a date",
                  "value": {
                    "afterDate": "2026-01-01T00:00:00Z"
                  }
                },
                "delete_by_ids": {
                  "summary": "Delete specific transactions",
                  "value": {
                    "ids": [
                      "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                      "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch deletion completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchDeleteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/categories": {
      "get": {
        "tags": [
          "Categories"
        ],
        "summary": "List categories",
        "operationId": "listCategories",
        "responses": {
          "200": {
            "description": "Category reference list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/banks": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Search banks by name",
        "operationId": "searchBanks",
        "description": "Search stored banks by exact, case-insensitive name (surrounding whitespace is ignored).\nOptionally filter by ISO country of origin, not a country where the bank operates.\nRequires an API key, is rate limited, and costs zero credits. No enrichment or creation occurs.\nReturns all matching candidates in pages ordered by country (unknown last), then ID.\nNo match returns an empty array. Results are read directly from the database so backfilled\ndetails are available immediately. Pagination is not a snapshot across requests.\n",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "description": "Bank name; 1–200 characters after trimming. No fuzzy or alias matching.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "example": "ING"
          },
          {
            "name": "country",
            "in": "query",
            "description": "ISO 3166-1 alpha-2 country of origin; case-insensitive. Unknown countries do not match a filter.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "example": "NL"
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000,
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching bank candidates (possibly empty)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankSearchResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/banks/{id}": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Get bank",
        "operationId": "getBank",
        "description": "Retrieve a stored bank by ID. Requires an API key, is rate limited, and costs zero credits.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Bank found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/merchants/{id}": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Get merchant",
        "operationId": "getMerchant",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Merchant found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MerchantResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/locations/{id}": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Get location",
        "operationId": "getLocation",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Location found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/intermediaries/{id}": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Get intermediary",
        "operationId": "getIntermediary",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Intermediary found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntermediaryResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/report-issue": {
      "post": {
        "tags": [
          "Issue Reports"
        ],
        "summary": "Create issue report",
        "operationId": "createIssueReport",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportIssueRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Issue report created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueReportResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "get": {
        "tags": [
          "Issue Reports"
        ],
        "summary": "List issue reports",
        "operationId": "listIssueReports",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/IssueReportStatus"
            }
          },
          {
            "name": "transaction_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated issue reports",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueReportListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/v1/report-issue/{id}": {
      "get": {
        "tags": [
          "Issue Reports"
        ],
        "summary": "Get issue report",
        "operationId": "getIssueReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Issue report detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueReportResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Public API key"
      }
    },
    "parameters": {
      "IdPath": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "schemas": {
      "ResponseMeta": {
        "type": "object",
        "required": [
          "generatedAt",
          "requestId",
          "version"
        ],
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "requestId": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "PaginationMeta": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ResponseMeta"
          },
          {
            "type": "object",
            "required": [
              "page",
              "size",
              "total",
              "totalPages"
            ],
            "properties": {
              "page": {
                "type": "integer"
              },
              "size": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "totalPages": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "ErrorDetails": {
        "type": "object",
        "properties": {
          "fieldErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": true
      },
      "ErrorObject": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "$ref": "#/components/schemas/ErrorDetails"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "$ref": "#/components/schemas/ErrorObject"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "DuplicateRequestErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "details"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "DUPLICATE_REQUEST"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "required": [
                  "requestId"
                ],
                "properties": {
                  "requestId": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string",
                    "enum": [
                      "in_progress",
                      "completed"
                    ]
                  },
                  "retryAfterSeconds": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        }
      },
      "ClientDisconnectedErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "CLIENT_DISCONNECTED"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "status",
              "service",
              "version"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "healthy"
                ]
              },
              "service": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "ApiInfoResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "version",
              "endpoints"
            ],
            "properties": {
              "version": {
                "type": "string",
                "enum": [
                  "v1"
                ]
              },
              "endpoints": {
                "type": "object",
                "required": [
                  "transactions",
                  "categories",
                  "banks",
                  "bank",
                  "merchants",
                  "locations",
                  "intermediaries",
                  "reportIssue"
                ],
                "properties": {
                  "transactions": {
                    "type": "string",
                    "example": "/v1/transactions"
                  },
                  "categories": {
                    "type": "string",
                    "example": "/v1/categories"
                  },
                  "banks": {
                    "type": "string",
                    "example": "/v1/banks"
                  },
                  "bank": {
                    "type": "string",
                    "example": "/v1/banks/{id}"
                  },
                  "merchants": {
                    "type": "string",
                    "example": "/v1/merchants/{id}"
                  },
                  "locations": {
                    "type": "string",
                    "example": "/v1/locations/{id}"
                  },
                  "intermediaries": {
                    "type": "string",
                    "example": "/v1/intermediaries/{id}"
                  },
                  "reportIssue": {
                    "type": "string",
                    "example": "/v1/report-issue"
                  }
                }
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "EnrichRequest": {
        "type": "object",
        "required": [
          "title",
          "country",
          "type"
        ],
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "Raw transaction description from the bank statement."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Za-z]{2}$",
            "description": "ISO 3166-1 alpha-2 country code (e.g., US, GB, DE).\nBoth upper and lowercase are accepted; the API normalizes to uppercase.\n"
          },
          "type": {
            "$ref": "#/components/schemas/TransactionType"
          },
          "options": {
            "$ref": "#/components/schemas/EnrichRequestOptions"
          }
        }
      },
      "EnrichRequestOptions": {
        "type": "object",
        "description": "Optional enrichment controls. Use `filters` to skip specific entity types,\nor pre-fill known entity data to improve accuracy and reduce latency.\n\n**Mutual exclusivity:** a filter flag (e.g. `noMerchant`) cannot be combined with\npre-filled data for the same entity type.\n",
        "properties": {
          "filters": {
            "$ref": "#/components/schemas/EnrichmentFilterOptions"
          },
          "merchant": {
            "$ref": "#/components/schemas/PrefilledMerchant"
          },
          "location": {
            "$ref": "#/components/schemas/PrefilledLocation"
          },
          "intermediaries": {
            "type": "array",
            "description": "Up to 5 pre-filled intermediary entries.",
            "maxItems": 5,
            "items": {
              "$ref": "#/components/schemas/PrefilledIntermediary"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "required": [
                "filters"
              ],
              "properties": {
                "filters": {
                  "type": "object",
                  "required": [
                    "noMerchant"
                  ],
                  "properties": {
                    "noMerchant": {
                      "const": true
                    }
                  }
                }
              }
            },
            "then": {
              "not": {
                "required": [
                  "merchant"
                ],
                "properties": {
                  "merchant": {
                    "type": "object",
                    "anyOf": [
                      {
                        "required": [
                          "id"
                        ]
                      },
                      {
                        "required": [
                          "name"
                        ]
                      },
                      {
                        "required": [
                          "domain"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "filters"
              ],
              "properties": {
                "filters": {
                  "type": "object",
                  "required": [
                    "noIntermediary"
                  ],
                  "properties": {
                    "noIntermediary": {
                      "const": true
                    }
                  }
                }
              }
            },
            "then": {
              "not": {
                "required": [
                  "intermediaries"
                ],
                "properties": {
                  "intermediaries": {
                    "type": "array",
                    "minItems": 1
                  }
                }
              }
            }
          },
          {
            "if": {
              "required": [
                "filters"
              ],
              "properties": {
                "filters": {
                  "type": "object",
                  "required": [
                    "noLocation"
                  ],
                  "properties": {
                    "noLocation": {
                      "const": true
                    }
                  }
                }
              }
            },
            "then": {
              "not": {
                "required": [
                  "location"
                ],
                "properties": {
                  "location": {
                    "type": "object",
                    "anyOf": [
                      {
                        "required": [
                          "cityName"
                        ]
                      },
                      {
                        "required": [
                          "physicalLocation"
                        ]
                      },
                      {
                        "required": [
                          "coordinates"
                        ]
                      },
                      {
                        "required": [
                          "streetName"
                        ]
                      },
                      {
                        "required": [
                          "storeNumber"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        ]
      },
      "EnrichmentFilterOptions": {
        "type": "object",
        "description": "Disable extraction of specific entity types from the transaction title.",
        "properties": {
          "noMerchant": {
            "type": "boolean",
            "description": "When `true`, merchant extraction is skipped entirely."
          },
          "noIntermediary": {
            "type": "boolean",
            "description": "When `true`, intermediary (payment processor) extraction is skipped."
          },
          "noLocation": {
            "type": "boolean",
            "description": "When `true`, location extraction is skipped."
          }
        }
      },
      "PrefilledMerchant": {
        "type": "object",
        "description": "Supply known merchant data to bypass or augment merchant extraction.\nWhen `id` is provided, the merchant is resolved by primary key (returns 422 if not found).\n`name` and `domain` perform best-effort lookups and fall through gracefully.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Existing Triqai merchant UUID."
          },
          "name": {
            "type": "string",
            "description": "Merchant display name for lookup."
          },
          "domain": {
            "type": "string",
            "description": "Merchant domain (e.g. `starbucks.com`)."
          }
        }
      },
      "PrefilledLocation": {
        "type": "object",
        "description": "Supply known location context to improve enrichment accuracy.\nWhen `coordinates` are provided and `cityName` is not set, the API resolves them to a\nplace name via reverse-geocoding and uses it as a location hint for AI title dissection.\n",
        "properties": {
          "cityName": {
            "type": "string",
            "description": "City name where the transaction occurred."
          },
          "physicalLocation": {
            "type": "boolean",
            "description": "Whether the transaction happened at a physical location."
          },
          "coordinates": {
            "type": "object",
            "description": "GPS coordinates of the transaction. When provided without `cityName`, coordinates are\nreverse-geocoded to resolve a place name. If no location is detected from transaction\ntitle text, the reverse-geocoded place becomes the fallback location.\n",
            "required": [
              "lat",
              "lng"
            ],
            "properties": {
              "lat": {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              "lng": {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              }
            }
          },
          "streetName": {
            "type": "string",
            "description": "Street name of the transaction location."
          },
          "storeNumber": {
            "type": "string",
            "description": "Store or branch number."
          }
        }
      },
      "PrefilledIntermediary": {
        "type": "object",
        "description": "Supply known intermediary (payment processor) data.\nWhen `id` is provided, the intermediary is resolved by primary key (returns 422 if not found).\n`name` and `domain` perform best-effort lookups.\n",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Existing Triqai intermediary UUID."
          },
          "name": {
            "type": "string",
            "description": "Intermediary display name for lookup."
          },
          "domain": {
            "type": "string",
            "description": "Intermediary domain (e.g. `paypal.com`)."
          }
        },
        "anyOf": [
          {
            "required": [
              "id"
            ]
          },
          {
            "required": [
              "name"
            ]
          },
          {
            "required": [
              "domain"
            ]
          }
        ]
      },
      "TransactionType": {
        "type": "string",
        "enum": [
          "expense",
          "income"
        ]
      },
      "EnrichmentErrorCode": {
        "type": "string",
        "enum": [
          "location_timeout",
          "merchant_scrape_failed",
          "processor_lookup_failed",
          "rate_limited",
          "internal_error",
          "title_dissection_failed"
        ]
      },
      "ConfidenceWithReasons": {
        "type": "object",
        "required": [
          "value",
          "reasons"
        ],
        "properties": {
          "value": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CategoryCode": {
        "type": "object",
        "required": [
          "mcc",
          "sic",
          "naics"
        ],
        "properties": {
          "mcc": {
            "type": "integer"
          },
          "sic": {
            "type": "integer"
          },
          "naics": {
            "type": "integer"
          }
        }
      },
      "Category": {
        "type": "object",
        "required": [
          "name",
          "code"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "code": {
            "$ref": "#/components/schemas/CategoryCode"
          }
        }
      },
      "CategoryStructure": {
        "type": "object",
        "required": [
          "primary",
          "secondary",
          "tertiary",
          "confidence"
        ],
        "properties": {
          "primary": {
            "$ref": "#/components/schemas/Category"
          },
          "secondary": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Category"
              },
              {
                "type": "null"
              }
            ]
          },
          "tertiary": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Category"
              },
              {
                "type": "null"
              }
            ]
          },
          "confidence": {
            "$ref": "#/components/schemas/ConfidenceWithReasons"
          }
        }
      },
      "Coordinates": {
        "type": "object",
        "required": [
          "latitude",
          "longitude"
        ],
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "StructuredAddress": {
        "type": "object",
        "required": [
          "street",
          "city",
          "state",
          "postalCode",
          "country",
          "countryName",
          "coordinates",
          "timezone"
        ],
        "properties": {
          "street": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "countryName": {
            "type": "string"
          },
          "coordinates": {
            "$ref": "#/components/schemas/Coordinates"
          },
          "timezone": {
            "type": "string"
          }
        }
      },
      "MerchantData": {
        "type": "object",
        "required": [
          "id",
          "name",
          "alias",
          "icon",
          "color",
          "website",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "alias": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "type": "array",
            "description": "Search keywords associated with this merchant. May be absent.",
            "items": {
              "type": "string"
            }
          },
          "icon": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string",
            "description": "Brief description of the merchant. May be absent."
          },
          "color": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "website": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "domain": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "category": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CategoryStructure"
              },
              {
                "type": "null"
              }
            ],
            "description": "Merchant category classification. Present on `GET /v1/merchants/{id}` responses."
          }
        }
      },
      "MerchantEntityData": {
        "type": "object",
        "required": [
          "id",
          "name",
          "alias",
          "icon",
          "color",
          "website",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "alias": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "type": "array",
            "description": "Search keywords associated with this merchant. May be absent.",
            "items": {
              "type": "string"
            }
          },
          "icon": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string",
            "description": "Brief description of the merchant. May be absent."
          },
          "color": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "website": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "domain": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "LocationRating": {
        "type": "object",
        "required": [
          "average",
          "count",
          "source"
        ],
        "properties": {
          "average": {
            "type": "number"
          },
          "count": {
            "type": "integer"
          },
          "source": {
            "type": "string"
          }
        }
      },
      "LocationData": {
        "type": "object",
        "required": [
          "id",
          "name",
          "formatted",
          "phoneNumber",
          "structured"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Location display name (store/branch name)."
          },
          "formatted": {
            "type": "string",
            "description": "Human-readable formatted address string."
          },
          "phoneNumber": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Phone number if available."
          },
          "website": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ],
            "description": "Location-specific website URL. May be absent."
          },
          "priceRange": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Price range indicator (e.g. \"$\", \"$$\"). May be absent."
          },
          "rating": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LocationRating"
              },
              {
                "type": "null"
              }
            ],
            "description": "User rating data from external sources. May be absent."
          },
          "structured": {
            "$ref": "#/components/schemas/StructuredAddress"
          }
        }
      },
      "IntermediaryData": {
        "type": "object",
        "required": [
          "id",
          "name",
          "icon",
          "description",
          "color",
          "website",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "icon": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "color": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "website": {
            "oneOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "domain": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "IntermediaryRecord": {
        "allOf": [
          {
            "$ref": "#/components/schemas/IntermediaryData"
          },
          {
            "type": "object",
            "required": [
              "role"
            ],
            "properties": {
              "role": {
                "type": "string"
              }
            }
          }
        ]
      },
      "PersonData": {
        "type": "object",
        "required": [
          "displayName"
        ],
        "properties": {
          "displayName": {
            "type": "string"
          }
        }
      },
      "EntityResult": {
        "type": "object",
        "required": [
          "type",
          "role",
          "confidence",
          "data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "merchant",
              "location",
              "intermediary",
              "person"
            ]
          },
          "role": {
            "type": "string"
          },
          "confidence": {
            "$ref": "#/components/schemas/ConfidenceWithReasons"
          },
          "data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MerchantEntityData"
              },
              {
                "$ref": "#/components/schemas/LocationData"
              },
              {
                "$ref": "#/components/schemas/IntermediaryData"
              },
              {
                "$ref": "#/components/schemas/PersonData"
              }
            ]
          }
        }
      },
      "TransactionData": {
        "type": "object",
        "required": [
          "category",
          "confidence"
        ],
        "properties": {
          "category": {
            "$ref": "#/components/schemas/CategoryStructure"
          },
          "confidence": {
            "$ref": "#/components/schemas/ConfidenceWithReasons"
          }
        }
      },
      "EnrichmentData": {
        "type": "object",
        "required": [
          "transaction",
          "entities"
        ],
        "properties": {
          "transaction": {
            "$ref": "#/components/schemas/TransactionData"
          },
          "entities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityResult"
            }
          }
        }
      },
      "EnrichMeta": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ResponseMeta"
          },
          {
            "type": "object",
            "required": [
              "categoryVersion",
              "transactionId"
            ],
            "properties": {
              "categoryVersion": {
                "type": "string"
              },
              "transactionId": {
                "type": "string",
                "format": "uuid",
                "description": "Identifier of the enriched transaction."
              },
              "errors": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EnrichmentErrorCode"
                }
              }
            }
          }
        ]
      },
      "EnrichSuccessResponse": {
        "type": "object",
        "required": [
          "success",
          "partial",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "partial": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EnrichmentData"
          },
          "meta": {
            "$ref": "#/components/schemas/EnrichMeta"
          }
        }
      },
      "TransactionRecord": {
        "type": "object",
        "required": [
          "id",
          "raw",
          "country",
          "direction",
          "status",
          "partial",
          "errors",
          "processingTimeMs",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "raw": {
            "type": "string"
          },
          "country": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "direction": {
            "$ref": "#/components/schemas/TransactionType"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "success",
              "partial",
              "error"
            ]
          },
          "partial": {
            "type": "boolean"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "processingTimeMs": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EnrichedTransaction": {
        "allOf": [
          {
            "$ref": "#/components/schemas/TransactionRecord"
          },
          {
            "type": "object",
            "properties": {
              "transaction": {
                "$ref": "#/components/schemas/TransactionData"
              },
              "entities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EntityResult"
                }
              }
            }
          }
        ]
      },
      "TransactionPagination": {
        "type": "object",
        "required": [
          "page",
          "size",
          "total",
          "totalPages"
        ],
        "properties": {
          "page": {
            "type": "integer"
          },
          "size": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          }
        }
      },
      "TransactionListResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "transactions",
              "pagination"
            ],
            "properties": {
              "transactions": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EnrichedTransaction"
                }
              },
              "pagination": {
                "$ref": "#/components/schemas/TransactionPagination"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "TransactionDetailResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "transaction"
            ],
            "properties": {
              "transaction": {
                "$ref": "#/components/schemas/EnrichedTransaction"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "DeleteTransactionResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "deleted",
              "transactionId"
            ],
            "properties": {
              "deleted": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "transactionId": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "TransactionCountResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "count"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "BatchDeleteRequest": {
        "type": "object",
        "description": "Provide exactly one of `all`, `afterDate`, or `ids`.\n",
        "oneOf": [
          {
            "required": [
              "all"
            ],
            "properties": {
              "all": {
                "type": "boolean",
                "enum": [
                  true
                ],
                "description": "When `true`, deletes all transactions for the organization."
              }
            }
          },
          {
            "required": [
              "afterDate"
            ],
            "properties": {
              "afterDate": {
                "type": "string",
                "format": "date-time",
                "description": "Delete all transactions created on or after this date."
              }
            }
          },
          {
            "required": [
              "ids"
            ],
            "properties": {
              "ids": {
                "type": "array",
                "description": "Delete specific transactions by UUID (max 1000).",
                "maxItems": 1000,
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        ]
      },
      "BatchDeleteResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "deleted",
              "count"
            ],
            "properties": {
              "deleted": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "count": {
                "type": "integer",
                "minimum": 0,
                "description": "Number of transactions deleted."
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "CategoryInfo": {
        "type": "object",
        "required": [
          "name",
          "type",
          "level",
          "parent",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "income",
              "expense",
              "transfer"
            ]
          },
          "level": {
            "type": "integer",
            "enum": [
              1,
              2,
              3
            ]
          },
          "parent": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string"
          },
          "mcc": {
            "type": "integer"
          },
          "sic": {
            "type": "integer"
          },
          "naics": {
            "type": "integer"
          }
        }
      },
      "CategoryListMeta": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ResponseMeta"
          },
          {
            "type": "object",
            "required": [
              "categoryVersion"
            ],
            "properties": {
              "categoryVersion": {
                "type": "string"
              }
            }
          }
        ]
      },
      "CategoryListResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "categories",
              "total"
            ],
            "properties": {
              "categories": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/CategoryInfo"
                }
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/CategoryListMeta"
          }
        }
      },
      "BankData": {
        "type": "object",
        "description": "Shared bank reference data. Unknown profile values are null; icon is the bank logo URL.",
        "required": [
          "id",
          "name",
          "country",
          "foundedYear",
          "foundedOn",
          "description",
          "icon",
          "color",
          "website",
          "domain"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[A-Z]{2}$",
            "description": "ISO 3166-1 alpha-2 country of origin, not countries of operation.",
            "example": "NL"
          },
          "foundedYear": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 9999,
            "description": "Founding year when known. May be populated without an exact date."
          },
          "foundedOn": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Exact founding date when known (YYYY-MM-DD). Never inferred from the year alone."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "icon": {
            "type": [
              "string",
              "null"
            ],
            "description": "Bank logo URL, consistent with merchant icon fields."
          },
          "color": {
            "type": [
              "string",
              "null"
            ],
            "description": "Brand color."
          },
          "website": {
            "type": [
              "string",
              "null"
            ]
          },
          "domain": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "BankResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "bank"
            ],
            "properties": {
              "bank": {
                "$ref": "#/components/schemas/BankData"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "BankSearchResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "banks",
              "pagination"
            ],
            "properties": {
              "banks": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BankData"
                }
              },
              "pagination": {
                "type": "object",
                "required": [
                  "page",
                  "size",
                  "hasMore"
                ],
                "properties": {
                  "page": {
                    "type": "integer"
                  },
                  "size": {
                    "type": "integer"
                  },
                  "hasMore": {
                    "type": "boolean",
                    "description": "More candidates exist; request the next page with the same filters and size."
                  }
                }
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "MerchantResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "merchant"
            ],
            "properties": {
              "merchant": {
                "$ref": "#/components/schemas/MerchantData"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "LocationResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "location"
            ],
            "properties": {
              "location": {
                "$ref": "#/components/schemas/LocationData"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "IntermediaryResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "intermediary"
            ],
            "properties": {
              "intermediary": {
                "$ref": "#/components/schemas/IntermediaryData"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "EnrichmentFieldPath": {
        "type": "string",
        "enum": [
          "transaction",
          "transaction.category",
          "transaction.category.primary",
          "transaction.category.primary.name",
          "transaction.category.primary.code",
          "transaction.category.primary.code.mcc",
          "transaction.category.primary.code.sic",
          "transaction.category.primary.code.naics",
          "transaction.category.secondary",
          "transaction.category.secondary.name",
          "transaction.category.secondary.code",
          "transaction.category.secondary.code.mcc",
          "transaction.category.secondary.code.sic",
          "transaction.category.secondary.code.naics",
          "transaction.category.tertiary",
          "transaction.category.tertiary.name",
          "transaction.category.tertiary.code",
          "transaction.category.tertiary.code.mcc",
          "transaction.category.tertiary.code.sic",
          "transaction.category.tertiary.code.naics",
          "transaction.category.confidence",
          "transaction.confidence",
          "entities",
          "entities.merchant",
          "entities.merchant.data",
          "entities.merchant.data.name",
          "entities.merchant.data.icon",
          "entities.merchant.data.website",
          "entities.merchant.data.description",
          "entities.location",
          "entities.location.data",
          "entities.location.data.name",
          "entities.location.data.formatted",
          "entities.location.data.structured",
          "entities.location.data.structured.city",
          "entities.location.data.structured.country",
          "entities.intermediary",
          "entities.intermediary.data",
          "entities.intermediary.data.name",
          "entities.intermediary.data.icon",
          "entities.person",
          "entities.person.data",
          "entities.person.data.displayName"
        ]
      },
      "IssueReportStatus": {
        "type": "string",
        "enum": [
          "pending",
          "reviewing",
          "resolved",
          "dismissed"
        ]
      },
      "ReportIssueRequest": {
        "type": "object",
        "required": [
          "transaction_id",
          "description",
          "fields"
        ],
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "Transaction identifier returned as `meta.transactionId` by the enrichment response. This is not `meta.requestId`, and the transaction must still exist in the organization's activity history."
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "fields": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "description": "Enrichment response field paths to report, such as `transaction.category.primary.name`.",
            "items": {
              "$ref": "#/components/schemas/EnrichmentFieldPath"
            }
          }
        }
      },
      "IssueReport": {
        "type": "object",
        "required": [
          "id",
          "transactionId",
          "description",
          "fields",
          "status",
          "statusMessage",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "transactionId": {
            "type": "string",
            "format": "uuid"
          },
          "description": {
            "type": "string"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "$ref": "#/components/schemas/IssueReportStatus"
          },
          "statusMessage": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "IssueReportResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "object",
            "required": [
              "issueReport"
            ],
            "properties": {
              "issueReport": {
                "$ref": "#/components/schemas/IssueReport"
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        }
      },
      "IssueReportListResponse": {
        "type": "object",
        "required": [
          "success",
          "data",
          "meta"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssueReport"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Authentication failed or missing credentials",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "authentication_error",
                "message": "API key is required"
              },
              "meta": {
                "generatedAt": "2026-02-16T00:00:00Z",
                "requestId": "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                "version": "1.1.2"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but not authorized",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "authorization_error",
                "message": "Access denied"
              },
              "meta": {
                "generatedAt": "2026-02-16T00:00:00Z",
                "requestId": "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                "version": "1.1.2"
              }
            }
          }
        }
      },
      "ValidationError": {
        "description": "Request validation failed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "validation_error",
                "message": "Validation failed",
                "details": {
                  "fieldErrors": {
                    "title": [
                      "Title is required"
                    ]
                  }
                }
              },
              "meta": {
                "generatedAt": "2026-02-16T00:00:00Z",
                "requestId": "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                "version": "1.1.2"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "Insufficient credits",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "insufficient_credits",
                "message": "Insufficient credits"
              },
              "meta": {
                "generatedAt": "2026-02-16T00:00:00Z",
                "requestId": "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                "version": "1.1.2"
              }
            }
          }
        }
      },
      "DuplicateRequest": {
        "description": "Duplicate idempotent request (completed or in-progress)",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Present when `details.state=in_progress`; value is in seconds."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DuplicateRequestErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Requests per second (sustained rate)"
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Current token-bucket capacity available"
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Timestamp when token bucket refills"
          },
          "X-RateLimit-Scope": {
            "schema": {
              "type": "string",
              "enum": [
                "rps",
                "concurrency"
              ]
            },
            "description": "Active limiting dimension"
          },
          "X-RateLimit-Concurrency-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Max concurrent requests for the org"
          },
          "X-RateLimit-Concurrency-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Remaining concurrent request slots"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until retry is allowed"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "rate_limited",
                "message": "Rate limit exceeded"
              },
              "meta": {
                "generatedAt": "2026-02-16T00:00:00Z",
                "requestId": "f353ca91-4fc5-49f2-9b9e-304f83d11914",
                "version": "1.1.2"
              }
            }
          }
        }
      },
      "ClientDisconnected": {
        "description": "Client closed request before completion",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientDisconnectedErrorResponse"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Service temporarily unavailable",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until retry is allowed"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "GatewayTimeout": {
        "description": "Upstream timeout",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
