openapi: 3.1.0 info: title: Expensify Integration Server API description: >- Best-effort OpenAPI for the Expensify Integration Server, documented at https://integrations.expensify.com/Integration-Server/doc/. The API exposes a single POST endpoint that takes a requestJobDescription JSON payload selecting a job type (file, reconciliation, download, create, get, update). Credentials (partnerUserID + partnerUserSecret) are passed in every payload. Rate limits: 5 requests / 10s and 20 requests / 60s. version: "1.0.0" contact: name: API Evangelist email: kin@apievangelist.com license: name: Proprietary servers: - url: https://integrations.expensify.com/Integration-Server description: Expensify Integration Server paths: /ExpensifyIntegrations: post: summary: Submit an integration job description: >- All Expensify Integration Server operations are dispatched through this single endpoint. The job type is selected by the type field on requestJobDescription. operationId: submitJob tags: [Integrations] requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: [requestJobDescription] properties: requestJobDescription: description: JSON string describing the job oneOf: - $ref: "#/components/schemas/FileJob" - $ref: "#/components/schemas/ReconciliationJob" - $ref: "#/components/schemas/DownloadJob" - $ref: "#/components/schemas/CreateJob" - $ref: "#/components/schemas/GetJob" - $ref: "#/components/schemas/UpdateJob" template: type: string description: ExpensiCode template (for type=file) responses: "200": description: Job response content: application/json: schema: $ref: "#/components/schemas/JobResponse" "429": description: Rate limit exceeded components: schemas: Credentials: type: object required: [partnerUserID, partnerUserSecret] properties: partnerUserID: { type: string } partnerUserSecret: { type: string } OnReceive: type: object properties: immediateResponse: type: array items: { type: string, enum: [returnRandomFileName] } FileJob: type: object required: [type, credentials, onReceive, inputSettings] properties: type: { type: string, enum: [file] } credentials: { $ref: "#/components/schemas/Credentials" } onReceive: { $ref: "#/components/schemas/OnReceive" } inputSettings: type: object properties: type: { type: string, enum: [combinedReportData] } filters: type: object properties: startDate: { type: string, format: date } endDate: { type: string, format: date } approvedAfter: { type: string, format: date } markedAsExported: { type: string } reportState: { type: string } limit: { type: integer } outputSettings: type: object properties: fileExtension: { type: string, enum: [csv, xlsx, pdf, json, xml] } fileBasename: { type: string } ReconciliationJob: type: object required: [type, credentials, inputSettings] properties: type: { type: string, enum: [reconciliation] } credentials: { $ref: "#/components/schemas/Credentials" } inputSettings: type: object properties: type: { type: string, enum: [reconciliation] } startDate: { type: string, format: date } endDate: { type: string, format: date } cardID: { type: string } domain: { type: string } DownloadJob: type: object required: [type, credentials, fileName, fileSystem] properties: type: { type: string, enum: [download] } credentials: { $ref: "#/components/schemas/Credentials" } fileName: { type: string } fileSystem: type: string enum: [integrationServer] CreateJob: type: object required: [type, credentials, inputSettings] properties: type: { type: string, enum: [create] } credentials: { $ref: "#/components/schemas/Credentials" } inputSettings: type: object properties: type: type: string enum: [report, expenses, policy, expenseRules] policyID: { type: string } report: type: object additionalProperties: true employeeEmail: { type: string } expenses: type: array items: type: object additionalProperties: true policy: type: object additionalProperties: true GetJob: type: object required: [type, credentials, inputSettings] properties: type: { type: string, enum: [get] } credentials: { $ref: "#/components/schemas/Credentials" } inputSettings: type: object properties: type: type: string enum: [policy, policyList, domainCardList] policyIDList: type: array items: { type: string } fields: type: array items: { type: string } adminOnly: { type: boolean } userEmail: { type: string } UpdateJob: type: object required: [type, credentials, inputSettings] properties: type: { type: string, enum: [update] } credentials: { $ref: "#/components/schemas/Credentials" } inputSettings: type: object properties: type: type: string enum: [policy, employees, reportStatus, tagApprovers] policyID: { type: string } categories: type: array items: type: object additionalProperties: true tags: type: array items: type: object additionalProperties: true reportFields: type: array items: type: object additionalProperties: true employees: type: array items: type: object additionalProperties: true reportIDList: type: array items: { type: string } reportState: { type: string } JobResponse: type: object properties: responseCode: type: integer description: HTTP-style status code responseMessage: { type: string } fileName: { type: string } reportID: { type: string } policyID: { type: string } policyInfoList: type: array items: type: object additionalProperties: true