openapi: 3.0.3 info: title: Fyle Platform Advances Expenses API description: 'The Fyle Platform API (Fyle is now Sage Expense Management) exposes the objects behind Fyle''s spend and expense management product - expenses, expense reports, advances, categories, projects, cost centers, employees, merchants, corporate cards and their real-time transactions, files/receipts, and webhook subscriptions - as role-scoped REST resources. Every path is served under a role segment (admin, spender, approver, or common); this document models the admin, spender, and common surfaces most commonly used for accounting/HRMS integration. Authentication is OAuth 2.0 using the refresh-token grant: exchange a long-lived refresh token (with client_id and client_secret) at the token endpoint for a short-lived Bearer access token, then send it as `Authorization: Bearer `. List endpoints follow a PostgREST-style convention: `offset`, `limit`, and `order` query parameters are mandatory, and any response field can be filtered with operators like `id=eq.` or `updated_at=gte.`. A single resource is fetched by filtering on its id. Endpoint paths and HTTP verbs in this document are grounded in Fyle''s open-source Python Platform SDK (github.com/fylein/fyle-platform-sdk-py). Request and response object field shapes are modeled representatively - consult the live Stoplight reference at docs.fylehq.com for exhaustive schemas.' version: '1.0' contact: name: Fyle (Sage Expense Management) url: https://www.fylehq.com license: name: Proprietary url: https://www.fylehq.com/legal servers: - url: https://api.fylehq.com/platform/v1 description: Fyle Platform API (production cluster). The role segment (admin, spender, approver, common) is the first path element. security: - bearerAuth: [] tags: - name: Expenses description: Expenses across the organization (admin) or for the signed-in spender. paths: /admin/expenses: get: operationId: listAdminExpenses tags: - Expenses summary: List expenses (admin) description: Lists expenses submitted by any employee in the current organization. Supports rich PostgREST-style filtering on any response field and mandatory offset/limit/order pagination. parameters: - $ref: '#/components/parameters/Offset' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Order' - name: id in: query description: Filter by expense id, e.g. `eq.txXXXX` or `in.(txA,txB)`. schema: type: string - name: updated_at in: query description: Filter by last-updated timestamp, e.g. `gte.2026-01-01T00:00:00.000Z`. schema: type: string responses: '200': description: A page of expenses. content: application/json: schema: $ref: '#/components/schemas/ExpenseListResponse' '401': $ref: '#/components/responses/Unauthorized' post: operationId: upsertAdminExpense tags: - Expenses summary: Create or update an expense (admin) description: Creates a new expense or updates an existing one (upsert) in the organization. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseUpsertRequest' responses: '200': description: The created or updated expense. content: application/json: schema: $ref: '#/components/schemas/ExpenseResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /admin/expenses/accounting_export_summary/bulk: post: operationId: bulkUpsertAccountingExportSummary tags: - Expenses summary: Bulk update accounting export summary description: Bulk-updates the accounting export summary on many expenses (used to sync export status back from an accounting system). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BulkDataRequest' responses: '200': description: Bulk update result. content: application/json: schema: $ref: '#/components/schemas/ExpenseListResponse' '401': $ref: '#/components/responses/Unauthorized' /spender/expenses: get: operationId: listSpenderExpenses tags: - Expenses summary: List my expenses (spender) description: Lists the signed-in spender's own expenses with filtering and pagination. parameters: - $ref: '#/components/parameters/Offset' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Order' responses: '200': description: A page of the spender's expenses. content: application/json: schema: $ref: '#/components/schemas/ExpenseListResponse' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createSpenderExpense tags: - Expenses summary: Create an expense (spender) description: Creates an expense for the signed-in spender. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseUpsertRequest' responses: '200': description: The created expense. content: application/json: schema: $ref: '#/components/schemas/ExpenseResponse' '401': $ref: '#/components/responses/Unauthorized' /spender/expenses/attach_receipt: post: operationId: attachReceipt tags: - Expenses summary: Attach a receipt to an expense description: Attaches an already-uploaded file (receipt) to an existing expense. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DataObjectRequest' responses: '200': description: The updated expense. content: application/json: schema: $ref: '#/components/schemas/ExpenseResponse' '401': $ref: '#/components/responses/Unauthorized' /spender/expenses/create_from_receipt: post: operationId: createExpenseFromReceipt tags: - Expenses summary: Create an expense from a receipt description: Creates a draft expense from an uploaded receipt file, letting Fyle extract merchant, amount, and date. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DataObjectRequest' responses: '200': description: The created expense. content: application/json: schema: $ref: '#/components/schemas/ExpenseResponse' '401': $ref: '#/components/responses/Unauthorized' components: schemas: ExpenseUpsertRequest: type: object required: - data properties: data: $ref: '#/components/schemas/Expense' DataObjectRequest: type: object description: Generic upsert envelope; Fyle wraps the resource under a `data` object. required: - data properties: data: type: object additionalProperties: true ExpenseResponse: type: object properties: data: $ref: '#/components/schemas/Expense' Error: type: object properties: message: type: string error: type: string BulkDataRequest: type: object description: Generic bulk envelope; Fyle wraps a list of resources under `data`. required: - data properties: data: type: array items: type: object additionalProperties: true Expense: type: object properties: id: type: string description: Expense id, prefixed `tx`. example: txABC123 org_id: type: string employee_id: type: string merchant: type: string purpose: type: string category_id: type: string project_id: type: string cost_center_id: type: string report_id: type: string amount: type: number format: double currency: type: string example: USD foreign_amount: type: number format: double foreign_currency: type: string spent_at: type: string format: date-time is_reimbursable: type: boolean state: type: string description: Expense state, e.g. DRAFT, COMPLETE, APPROVER_PENDING, PAID. source: type: string description: Origin of the expense, e.g. CORPORATE_CARD, MOBILE, WEBAPP. file_ids: type: array items: type: string created_at: type: string format: date-time updated_at: type: string format: date-time ExpenseListResponse: type: object properties: count: type: integer offset: type: integer data: type: array items: $ref: '#/components/schemas/Expense' responses: BadRequest: description: One or more parameters are invalid. content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Missing, invalid, or expired access token. content: application/json: schema: $ref: '#/components/schemas/Error' parameters: Offset: name: offset in: query required: true description: Number of records to skip for pagination (mandatory). schema: type: integer minimum: 0 default: 0 Order: name: order in: query required: true description: Sort order, e.g. `created_at.desc` or `updated_at.asc` (mandatory). schema: type: string example: created_at.desc Limit: name: limit in: query required: true description: Maximum number of records to return per page (mandatory). schema: type: integer minimum: 1 default: 100 securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'OAuth 2.0 Bearer access token. Obtain it via the refresh-token grant at the Fyle OAuth token endpoint (accounts host) using your client_id, client_secret, and refresh_token, then send it as `Authorization: Bearer `.'