openapi: 3.1.0 info: title: SAP Concur Expense API description: >- SAP Concur Expense provides REST APIs for managing the full expense lifecycle including creating and submitting expense reports, managing individual expense entries, capturing receipt images, handling quick expenses, managing allocations across cost centers, and retrieving reimbursement payment batches. Authentication uses OAuth 2.0 with support for authorization code and refresh token flows. version: '3.0' contact: name: SAP Concur Developer Support url: https://developer.concur.com/support termsOfService: https://developer.concur.com/terms-of-use externalDocs: description: SAP Concur Expense API Reference url: https://developer.concur.com/api-reference/expense/ servers: - url: https://us.api.concursolutions.com/api/v3.0 description: United States Production - url: https://eu.api.concursolutions.com/api/v3.0 description: Europe Production - url: https://cn.api.concursolutions.com/api/v3.0 description: China Production tags: - name: Expense Reports description: >- Create, read, update, and submit expense reports. Manage the full report lifecycle from draft through approval and reimbursement. - name: Expense Entries description: >- Manage individual expense line items within expense reports including itemizations, attendees, and custom fields. - name: Quick Expenses description: >- Create and manage quick expenses captured outside of a formal report. Quick expenses can be promoted to full expense report entries. - name: Receipt Images description: >- Upload and retrieve receipt images associated with expense entries. Supports PNG, JPG, PDF, and TIFF image formats. - name: Allocations description: >- Manage cost center, project, or GL account allocations for expense entries. Supports percentage-based and amount-based splits. - name: Payment Batches description: >- Retrieve payment batch information for approved expense reports ready for reimbursement processing. - name: Group Configurations description: >- Retrieve expense group policy configurations including expense types, payment types, and workflow settings. security: - OAuth2: - expense.report.read - expense.report.write paths: /expense/reports: get: operationId: listExpenseReports summary: List Expense Reports description: >- Returns a collection of expense reports belonging to the current user or accessible via company-level access. Supports filtering by approval status, submission date, payment status, and reimbursement method. tags: - Expense Reports parameters: - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page (max 100) required: false schema: type: integer maximum: 100 - name: approvalStatusCode in: query description: >- Filter by approval status code. Valid values: A_AAFH, A_AAPH, A_ADMIN, A_APPR, A_EXTV, A_FILE, A_NOTF, A_PBDG, A_PECO, A_PEND, A_PVAL, A_RESU, A_RHLD, A_TEXP required: false schema: type: string - name: paymentStatusCode in: query description: >- Filter by payment status code. Valid values: P_HOLD, P_NOTP, P_PAID, P_PAYC, P_PROC required: false schema: type: string - name: modifiedDateBefore in: query description: Return reports modified before this date (ISO 8601 format) required: false schema: type: string format: date-time - name: modifiedDateAfter in: query description: Return reports modified after this date (ISO 8601 format) required: false schema: type: string format: date-time - name: userID in: query description: >- The login ID of the report owner. May only be used by company-level access token holders. required: false schema: type: string - name: reimbursementMethod in: query description: >- Filter by reimbursement method. Valid values: ADPPAYR, APCHECK, AVI, CNQRPAY, PMTSERV required: false schema: type: string responses: '200': description: Success - Returns list of expense reports content: application/json: schema: $ref: '#/components/schemas/ExpenseReportCollection' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error post: operationId: createExpenseReport summary: Create Expense Report description: >- Creates a new expense report header. After creating the report header, expense entries can be added using the expense entries endpoint. tags: - Expense Reports requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseReportCreate' responses: '200': description: Success - Returns the created expense report ID content: application/json: schema: $ref: '#/components/schemas/ExpenseReportCreateResponse' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error /expense/reports/{id}: get: operationId: getExpenseReport summary: Get Expense Report description: >- Returns a single expense report by its ID. Includes report header information such as approval status, totals, and submission date. tags: - Expense Reports parameters: - name: id in: path description: The unique identifier of the expense report required: true schema: type: string responses: '200': description: Success - Returns the expense report content: application/json: schema: $ref: '#/components/schemas/ExpenseReport' '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error put: operationId: updateExpenseReport summary: Update Expense Report description: >- Updates an existing expense report header. Only draft reports (not yet submitted) can be updated. tags: - Expense Reports parameters: - name: id in: path description: The unique identifier of the expense report required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseReportUpdate' responses: '204': description: Success - No content returned '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error delete: operationId: deleteExpenseReport summary: Delete Expense Report description: >- Deletes an expense report. Only draft reports that have never been submitted can be deleted. tags: - Expense Reports parameters: - name: id in: path description: The unique identifier of the expense report required: true schema: type: string responses: '204': description: Success - No content returned '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error /expense/entries: get: operationId: listExpenseEntries summary: List Expense Entries description: >- Returns a collection of expense entries for the specified report ID. Each entry represents a single expense line item with amount, date, category, and supporting details. tags: - Expense Entries parameters: - name: reportID in: query description: The unique identifier of the expense report required: true schema: type: string - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page (max 100) required: false schema: type: integer maximum: 100 responses: '200': description: Success - Returns list of expense entries content: application/json: schema: $ref: '#/components/schemas/ExpenseEntryCollection' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error post: operationId: createExpenseEntry summary: Create Expense Entry description: >- Creates a new expense entry within an expense report. The report must exist and be in draft state. The entry requires an expense type code, transaction date, and transaction amount. tags: - Expense Entries requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseEntryCreate' responses: '200': description: Success - Returns the created entry ID content: application/json: schema: $ref: '#/components/schemas/ExpenseEntryCreateResponse' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error /expense/entries/{id}: get: operationId: getExpenseEntry summary: Get Expense Entry description: >- Returns a single expense entry by its ID, including all form field values, itemizations, and attendee information. tags: - Expense Entries parameters: - name: id in: path description: The unique identifier of the expense entry required: true schema: type: string responses: '200': description: Success - Returns the expense entry content: application/json: schema: $ref: '#/components/schemas/ExpenseEntry' '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error put: operationId: updateExpenseEntry summary: Update Expense Entry description: >- Updates an existing expense entry. Only entries in draft reports can be modified. tags: - Expense Entries parameters: - name: id in: path description: The unique identifier of the expense entry required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseEntryUpdate' responses: '204': description: Success - No content returned '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error delete: operationId: deleteExpenseEntry summary: Delete Expense Entry description: Deletes an expense entry from a draft expense report. tags: - Expense Entries parameters: - name: id in: path description: The unique identifier of the expense entry required: true schema: type: string responses: '204': description: Success - No content returned '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error /expense/quickexpenses: get: operationId: listQuickExpenses summary: List Quick Expenses description: >- Returns quick expenses for the current user. Quick expenses are unassigned expense records captured before being added to an expense report. tags: - Quick Expenses parameters: - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page (max 100) required: false schema: type: integer maximum: 100 - name: modifiedDateBefore in: query description: Return quick expenses modified before this date required: false schema: type: string format: date-time - name: modifiedDateAfter in: query description: Return quick expenses modified after this date required: false schema: type: string format: date-time responses: '200': description: Success - Returns list of quick expenses content: application/json: schema: $ref: '#/components/schemas/QuickExpenseCollection' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error post: operationId: createQuickExpense summary: Create Quick Expense description: >- Creates a new quick expense record. Quick expenses can be created without an associated expense report and promoted to a full report entry later. tags: - Quick Expenses requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/QuickExpenseCreate' responses: '200': description: Success - Returns the created quick expense ID content: application/json: schema: $ref: '#/components/schemas/QuickExpenseCreateResponse' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error /expense/quickexpenses/{id}: get: operationId: getQuickExpense summary: Get Quick Expense description: Returns a single quick expense by its ID. tags: - Quick Expenses parameters: - name: id in: path description: The unique identifier of the quick expense required: true schema: type: string responses: '200': description: Success - Returns the quick expense content: application/json: schema: $ref: '#/components/schemas/QuickExpense' '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error put: operationId: updateQuickExpense summary: Update Quick Expense description: Updates an existing quick expense record. tags: - Quick Expenses parameters: - name: id in: path description: The unique identifier of the quick expense required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/QuickExpenseUpdate' responses: '204': description: Success - No content returned '400': description: Bad Request '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error delete: operationId: deleteQuickExpense summary: Delete Quick Expense description: Deletes a quick expense record. tags: - Quick Expenses parameters: - name: id in: path description: The unique identifier of the quick expense required: true schema: type: string responses: '204': description: Success - No content returned '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error /expense/receiptimages: get: operationId: listReceiptImages summary: List Receipt Images description: >- Returns a collection of receipt images associated with expense entries for the current user. tags: - Receipt Images parameters: - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page (max 100) required: false schema: type: integer maximum: 100 - name: entryID in: query description: Filter receipt images by expense entry ID required: false schema: type: string responses: '200': description: Success - Returns list of receipt images content: application/json: schema: $ref: '#/components/schemas/ReceiptImageCollection' '401': description: Unauthorized '500': description: Internal Server Error post: operationId: createReceiptImage summary: Upload Receipt Image description: >- Uploads a new receipt image. The image can be in PNG, JPG, PDF, or TIFF format and will be associated with an expense entry. tags: - Receipt Images requestBody: required: true content: image/png: schema: type: string format: binary image/jpeg: schema: type: string format: binary application/pdf: schema: type: string format: binary responses: '200': description: Success - Returns receipt image ID content: application/json: schema: $ref: '#/components/schemas/ReceiptImageCreateResponse' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error /expense/receiptimages/{id}: get: operationId: getReceiptImage summary: Get Receipt Image description: Returns the receipt image URL for the specified image ID. tags: - Receipt Images parameters: - name: id in: path description: The unique identifier of the receipt image required: true schema: type: string responses: '200': description: Success - Returns the receipt image content: application/json: schema: $ref: '#/components/schemas/ReceiptImage' '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error delete: operationId: deleteReceiptImage summary: Delete Receipt Image description: Deletes a receipt image by its ID. tags: - Receipt Images parameters: - name: id in: path description: The unique identifier of the receipt image required: true schema: type: string responses: '204': description: Success - No content returned '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error /expense/allocations: get: operationId: listAllocations summary: List Expense Allocations description: >- Returns expense allocations for the specified entry ID. Allocations split an expense across multiple cost centers, projects, or GL accounts. tags: - Allocations parameters: - name: entryID in: query description: The expense entry ID to retrieve allocations for required: true schema: type: string - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page (max 100) required: false schema: type: integer maximum: 100 responses: '200': description: Success - Returns list of allocations content: application/json: schema: $ref: '#/components/schemas/AllocationCollection' '400': description: Bad Request '401': description: Unauthorized '500': description: Internal Server Error /expense/expensegroupconfigurations: get: operationId: listExpenseGroupConfigurations summary: List Expense Group Configurations description: >- Returns expense group policy configurations for the current user. Configurations define available expense types, payment types, allowable business purposes, and workflow approval rules. tags: - Group Configurations parameters: - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page required: false schema: type: integer - name: userID in: query description: The login ID of the user to retrieve configurations for required: false schema: type: string responses: '200': description: Success - Returns expense group configurations content: application/json: schema: $ref: '#/components/schemas/ExpenseGroupConfigCollection' '401': description: Unauthorized '500': description: Internal Server Error /expense/expensegroupconfigurations/{id}: get: operationId: getExpenseGroupConfiguration summary: Get Expense Group Configuration description: Returns a single expense group configuration by its ID. tags: - Group Configurations parameters: - name: id in: path description: The unique identifier of the expense group configuration required: true schema: type: string responses: '200': description: Success - Returns the expense group configuration content: application/json: schema: $ref: '#/components/schemas/ExpenseGroupConfig' '401': description: Unauthorized '404': description: Not Found '500': description: Internal Server Error /expense/paymentbatches: get: operationId: listPaymentBatches summary: List Payment Batches description: >- Returns payment batches for approved expense reports ready for reimbursement. Payment batches group multiple expense reports into a single payment run. tags: - Payment Batches parameters: - name: offset in: query description: Starting page offset for pagination required: false schema: type: string - name: limit in: query description: Number of records to return per page required: false schema: type: integer - name: batchID in: query description: Filter by specific payment batch ID required: false schema: type: string responses: '200': description: Success - Returns list of payment batches content: application/json: schema: $ref: '#/components/schemas/PaymentBatchCollection' '401': description: Unauthorized '500': description: Internal Server Error components: securitySchemes: OAuth2: type: oauth2 flows: authorizationCode: authorizationUrl: https://us.api.concursolutions.com/oauth2/v0/authorize tokenUrl: https://us.api.concursolutions.com/oauth2/v0/token scopes: expense.report.read: Read expense reports expense.report.write: Create and modify expense reports expense.report.delete: Delete expense reports schemas: ExpenseReportCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/ExpenseReport' NextPage: type: string description: URL to the next page of results ExpenseReport: type: object properties: ID: type: string description: The unique identifier of the expense report Name: type: string description: The name of the expense report Total: type: number format: double description: Total amount of all expenses in the report CurrencyCode: type: string description: ISO 4217 currency code for the report total ApprovalStatusCode: type: string description: Current approval status code ApprovalStatusName: type: string description: Human-readable approval status name PaymentStatusCode: type: string description: Current payment status code PaymentStatusName: type: string description: Human-readable payment status name SubmitDate: type: string format: date-time description: Date the report was submitted for approval CreateDate: type: string format: date-time description: Date the report was created ProcessingPaymentDate: type: string format: date-time description: Date payment processing began OwnerLoginID: type: string description: Login ID of the report owner OwnerName: type: string description: Full name of the report owner PolicyID: type: string description: The expense policy ID applied to this report ReportNumber: type: string description: Human-readable report number HasException: type: boolean description: Whether the report has policy exceptions URI: type: string description: URI to retrieve this resource ExpenseReportCreate: type: object required: - Name properties: Name: type: string description: The name of the expense report Comment: type: string description: Additional comments for the report PolicyID: type: string description: The expense policy ID to apply Purpose: type: string description: Business purpose for the expenses UserDefinedDate: type: string format: date-time description: User-defined date for the report ExpenseReportCreateResponse: type: object properties: ID: type: string description: The unique identifier of the created expense report URI: type: string description: URI of the created resource ExpenseReportUpdate: type: object properties: Name: type: string description: Updated name for the expense report Comment: type: string description: Updated comment Purpose: type: string description: Updated business purpose ExpenseEntryCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/ExpenseEntry' NextPage: type: string description: URL to the next page of results ExpenseEntry: type: object properties: ID: type: string description: The unique identifier of the expense entry ReportID: type: string description: The parent expense report ID ExpenseTypeCode: type: string description: Expense type code (e.g., BUSML, AIRFR, HOTEL) ExpenseTypeName: type: string description: Human-readable expense type name TransactionDate: type: string format: date description: Date of the expense transaction TransactionAmount: type: number format: double description: Amount of the transaction in transaction currency TransactionCurrencyCode: type: string description: ISO 4217 currency code of the transaction PostedAmount: type: number format: double description: Amount posted in report currency BusinessPurpose: type: string description: Business purpose for the expense VendorDescription: type: string description: Name of the vendor or merchant LocationName: type: string description: Location where expense was incurred IsItemized: type: boolean description: Whether the entry has been itemized HasVAT: type: boolean description: Whether VAT tax applies to this entry ReceiptImageID: type: string description: ID of the associated receipt image URI: type: string description: URI to retrieve this resource ExpenseEntryCreate: type: object required: - ReportID - ExpenseTypeCode - TransactionDate - TransactionAmount - TransactionCurrencyCode properties: ReportID: type: string description: The parent expense report ID ExpenseTypeCode: type: string description: Expense type code TransactionDate: type: string format: date description: Date of the expense transaction TransactionAmount: type: number format: double description: Amount of the transaction TransactionCurrencyCode: type: string description: ISO 4217 currency code BusinessPurpose: type: string description: Business purpose for the expense VendorDescription: type: string description: Vendor or merchant name LocationName: type: string description: Location where expense was incurred Comment: type: string description: Additional notes ExpenseEntryCreateResponse: type: object properties: ID: type: string description: The unique identifier of the created expense entry URI: type: string description: URI of the created resource ExpenseEntryUpdate: type: object properties: ExpenseTypeCode: type: string description: Updated expense type code TransactionDate: type: string format: date description: Updated transaction date TransactionAmount: type: number format: double description: Updated transaction amount BusinessPurpose: type: string description: Updated business purpose VendorDescription: type: string description: Updated vendor description Comment: type: string description: Updated comment QuickExpenseCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/QuickExpense' NextPage: type: string QuickExpense: type: object properties: QuickExpenseKey: type: string description: The unique identifier of the quick expense ExpenseTypeCode: type: string description: Expense type code ExpenseTypeName: type: string description: Human-readable expense type name TransactionDate: type: string format: date description: Date of the expense TransactionAmount: type: number format: double description: Amount of the expense CurrencyCode: type: string description: ISO 4217 currency code Comment: type: string description: Optional comment or description VendorDescription: type: string description: Vendor or merchant name LocationName: type: string description: Location name ReceiptImageID: type: string description: Associated receipt image ID OwnerLoginID: type: string description: Login ID of the expense owner URI: type: string QuickExpenseCreate: type: object required: - TransactionDate - TransactionAmount - CurrencyCode properties: ExpenseTypeCode: type: string description: Expense type code TransactionDate: type: string format: date description: Date of the expense TransactionAmount: type: number format: double description: Amount of the expense CurrencyCode: type: string description: ISO 4217 currency code Comment: type: string description: Optional comment VendorDescription: type: string description: Vendor or merchant name LocationName: type: string description: Location of the expense QuickExpenseCreateResponse: type: object properties: ID: type: string description: The unique identifier of the created quick expense URI: type: string QuickExpenseUpdate: type: object properties: ExpenseTypeCode: type: string TransactionDate: type: string format: date TransactionAmount: type: number format: double CurrencyCode: type: string Comment: type: string VendorDescription: type: string ReceiptImageCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/ReceiptImage' NextPage: type: string ReceiptImage: type: object properties: ID: type: string description: The unique identifier of the receipt image EntryID: type: string description: The associated expense entry ID ReceiptImageURL: type: string description: Temporary URL to access the receipt image IsRequired: type: boolean description: Whether a receipt image is required for this entry URI: type: string ReceiptImageCreateResponse: type: object properties: ID: type: string description: The unique identifier of the uploaded receipt image URI: type: string AllocationCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/Allocation' NextPage: type: string Allocation: type: object properties: AllocationID: type: string description: The unique identifier of the allocation EntryID: type: string description: The associated expense entry ID Percentage: type: number format: double description: Percentage of the expense allocated to this cost object Amount: type: number format: double description: Amount allocated in report currency AccountCode1: type: string description: Primary GL account code AccountCode2: type: string description: Secondary GL account code Custom1: type: string description: Custom allocation field 1 (e.g., cost center) Custom2: type: string description: Custom allocation field 2 (e.g., project code) URI: type: string ExpenseGroupConfigCollection: type: object properties: Items: type: array items: $ref: '#/components/schemas/ExpenseGroupConfig' NextPage: type: string ExpenseGroupConfig: type: object properties: ID: type: string description: Expense group configuration ID Name: type: string description: Name of the expense group PolicyID: type: string description: Associated expense policy ID AllowUserDigitalTaxInvoice: type: boolean description: Whether users can attach digital tax invoices AllowUserRegisterYodlee: type: boolean description: Whether users can connect Yodlee bank feeds AttendeeListFormID: type: string description: Form ID used for attendee lists URI: type: string PaymentBatchCollection: type: object properties: PaymentBatches: type: array items: $ref: '#/components/schemas/PaymentBatch' NextPage: type: string PaymentBatch: type: object properties: BatchID: type: string description: The unique identifier of the payment batch BatchName: type: string description: Name of the payment batch BatchTotal: type: number format: double description: Total amount of the payment batch BatchCurrencyCode: type: string description: ISO 4217 currency code for the batch total Count: type: integer description: Number of expense reports in the batch PaymentMethod: type: string description: Payment method used for the batch BatchCloseDate: type: string format: date-time description: Date the payment batch was closed URI: type: string