Expense Report v3 API

Allows developers to read and write expense report headers, manage the expense report lifecycle including submission and approval workflows, and retrieve expense report data for integration with ERP and financial systems.

Documentation

Specifications

Other Resources

OpenAPI Specification

sap-concur-expense-report-openapi.yml Raw ↑
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: doubl

# --- truncated at 32 KB (40 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/sap-concur-expense/refs/heads/main/openapi/sap-concur-expense-report-openapi.yml