From e10ab76e8050de44b6ac6646a5884294b303e4cc Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 6 May 2026 18:17:27 -0700 Subject: [PATCH] fix(sap-concur): rename misleading exchange-rate tool, drop unusable refresh_token grant, validate geolocation host - Rename sap_concur_get_exchange_rate to sap_concur_upload_exchange_rates (POST bulk upload, not GET) - Remove refresh_token from SapConcurGrantType / Zod enum / block dropdown / docs (no implementation) - Validate Concur geolocation hostname against SAP_CONCUR_ALLOWED_DATACENTERS Co-Authored-By: Claude Opus 4.7 --- .../docs/content/docs/en/tools/sap_concur.mdx | 142 +++++++++--------- apps/sim/app/api/tools/sap_concur/shared.ts | 9 +- apps/sim/blocks/blocks/sap_concur.ts | 11 +- apps/sim/tools/registry.ts | 4 +- .../sap_concur/approve_expense_report.ts | 2 +- .../tools/sap_concur/associate_attendees.ts | 2 +- .../tools/sap_concur/create_cash_advance.ts | 2 +- .../sap_concur/create_expected_expense.ts | 2 +- .../tools/sap_concur/create_expense_report.ts | 2 +- apps/sim/tools/sap_concur/create_list_item.ts | 2 +- .../sap_concur/create_purchase_request.ts | 2 +- .../tools/sap_concur/create_quick_expense.ts | 2 +- .../create_quick_expense_with_image.ts | 2 +- .../tools/sap_concur/create_report_comment.ts | 2 +- .../tools/sap_concur/create_travel_request.ts | 2 +- apps/sim/tools/sap_concur/create_user.ts | 2 +- .../sap_concur/delete_expected_expense.ts | 2 +- apps/sim/tools/sap_concur/delete_expense.ts | 2 +- .../tools/sap_concur/delete_expense_report.ts | 2 +- apps/sim/tools/sap_concur/delete_list_item.ts | 2 +- .../tools/sap_concur/delete_travel_request.ts | 2 +- apps/sim/tools/sap_concur/delete_user.ts | 2 +- apps/sim/tools/sap_concur/get_allocation.ts | 2 +- apps/sim/tools/sap_concur/get_budget.ts | 2 +- apps/sim/tools/sap_concur/get_cash_advance.ts | 2 +- .../tools/sap_concur/get_expected_expense.ts | 2 +- apps/sim/tools/sap_concur/get_expense.ts | 2 +- .../tools/sap_concur/get_expense_report.ts | 2 +- apps/sim/tools/sap_concur/get_itemizations.ts | 2 +- apps/sim/tools/sap_concur/get_itinerary.ts | 2 +- apps/sim/tools/sap_concur/get_list.ts | 2 +- apps/sim/tools/sap_concur/get_list_item.ts | 2 +- .../tools/sap_concur/get_purchase_request.ts | 2 +- apps/sim/tools/sap_concur/get_receipt.ts | 2 +- .../tools/sap_concur/get_receipt_status.ts | 2 +- .../sap_concur/get_request_cash_advance.ts | 2 +- .../tools/sap_concur/get_travel_profile.ts | 2 +- .../tools/sap_concur/get_travel_request.ts | 2 +- apps/sim/tools/sap_concur/get_user.ts | 2 +- apps/sim/tools/sap_concur/index.ts | 2 +- .../tools/sap_concur/issue_cash_advance.ts | 2 +- apps/sim/tools/sap_concur/list_allocations.ts | 2 +- .../sap_concur/list_attendee_associations.ts | 2 +- .../sap_concur/list_budget_categories.ts | 2 +- apps/sim/tools/sap_concur/list_budgets.ts | 2 +- apps/sim/tools/sap_concur/list_exceptions.ts | 2 +- .../sap_concur/list_expected_expenses.ts | 2 +- .../tools/sap_concur/list_expense_reports.ts | 2 +- apps/sim/tools/sap_concur/list_expenses.ts | 2 +- apps/sim/tools/sap_concur/list_itineraries.ts | 2 +- apps/sim/tools/sap_concur/list_list_items.ts | 2 +- apps/sim/tools/sap_concur/list_lists.ts | 2 +- apps/sim/tools/sap_concur/list_receipts.ts | 2 +- .../tools/sap_concur/list_report_comments.ts | 2 +- .../sap_concur/list_reports_to_approve.ts | 2 +- .../list_travel_profiles_summary.ts | 2 +- .../list_travel_request_comments.ts | 2 +- .../tools/sap_concur/list_travel_requests.ts | 2 +- apps/sim/tools/sap_concur/list_users.ts | 2 +- .../tools/sap_concur/move_travel_request.ts | 2 +- .../tools/sap_concur/recall_expense_report.ts | 2 +- .../tools/sap_concur/remove_all_attendees.ts | 2 +- apps/sim/tools/sap_concur/search_locations.ts | 2 +- apps/sim/tools/sap_concur/search_users.ts | 2 +- .../sap_concur/send_back_expense_report.ts | 2 +- .../tools/sap_concur/submit_expense_report.ts | 2 +- apps/sim/tools/sap_concur/types.ts | 4 +- .../sim/tools/sap_concur/update_allocation.ts | 2 +- .../sap_concur/update_expected_expense.ts | 2 +- apps/sim/tools/sap_concur/update_expense.ts | 2 +- .../tools/sap_concur/update_expense_report.ts | 2 +- apps/sim/tools/sap_concur/update_list_item.ts | 2 +- .../tools/sap_concur/update_travel_request.ts | 2 +- apps/sim/tools/sap_concur/update_user.ts | 2 +- ...hange_rate.ts => upload_exchange_rates.ts} | 13 +- .../tools/sap_concur/upload_receipt_image.ts | 2 +- 76 files changed, 165 insertions(+), 158 deletions(-) rename apps/sim/tools/sap_concur/{get_exchange_rate.ts => upload_exchange_rates.ts} (90%) diff --git a/apps/docs/content/docs/en/tools/sap_concur.mdx b/apps/docs/content/docs/en/tools/sap_concur.mdx index eb021460ef..4da75a6d36 100644 --- a/apps/docs/content/docs/en/tools/sap_concur.mdx +++ b/apps/docs/content/docs/en/tools/sap_concur.mdx @@ -49,7 +49,7 @@ Approve an expense report as a manager (PATCH /expensereports/v4/reports/{report | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -74,7 +74,7 @@ Associate attendees with an expense (POST /expensereports/v4/users/{userId}/cont | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -103,7 +103,7 @@ Create a cash advance (POST /cashadvance/v4/cashadvances). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -128,7 +128,7 @@ Create an expected expense on a travel request (POST /travelrequest/v4/requests/ | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -169,7 +169,7 @@ Create an expense report (POST /expensereports/v4/users/{userId}/context/{contex | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -196,7 +196,7 @@ Create a list item (POST /list/v4/items). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -230,7 +230,7 @@ Create a purchase request (POST /purchaserequest/v4/purchaserequests). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -260,7 +260,7 @@ Create a quick expense (POST /quickexpense/v4/users/{userId}/context/TRAVELER/qu | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -287,7 +287,7 @@ Create a quick expense with an attached image (POST /quickexpense/v4/users/{user | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -315,7 +315,7 @@ Create a comment on a report (POST /expensereports/v4/users/{userId}/context/{co | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -343,7 +343,7 @@ Create a travel request (POST /travelrequest/v4/requests). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -430,7 +430,7 @@ Create a new user identity (POST /profile/identity/v4.1/Users). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -454,7 +454,7 @@ Delete an expected expense (DELETE /travelrequest/v4/expenses/{expenseUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -479,7 +479,7 @@ Delete an expense (DELETE /expensereports/v4/reports/{reportId}/expenses/{expens | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -504,7 +504,7 @@ Delete an expense report (DELETE /expensereports/v4/reports/{reportId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -528,7 +528,7 @@ Delete a list item (DELETE /list/v4/items/{itemId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -552,7 +552,7 @@ Delete a travel request (DELETE /travelrequest/v4/requests/{requestUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -577,7 +577,7 @@ Delete a user identity (DELETE /profile/identity/v4.1/Users/{id}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -601,7 +601,7 @@ Get a single allocation (GET /expensereports/v4/users/{userId}/context/{contextT | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -645,7 +645,7 @@ Get a budget item header by ID (GET /budget/v4/budgetItemHeader/{id}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -693,7 +693,7 @@ Get a cash advance (GET /cashadvance/v4/cashadvances/{cashadvanceId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -733,7 +733,7 @@ Get a cash advance (GET /cashadvance/v4/cashadvances/{cashadvanceId}). | ↳ `paymentCode` | string | Payment type code | | ↳ `description` | string | Payment method description | -### `sap_concur_get_exchange_rate` +### `sap_concur_upload_exchange_rates` Bulk upload up to 100 custom exchange rates (POST /exchangerate/v4/rates). Body: { currency_sets: [{ from_crn_code, to_crn_code, start_date: @@ -742,7 +742,7 @@ Bulk upload up to 100 custom exchange rates (POST /exchangerate/v4/rates). Body: | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -769,7 +769,7 @@ Get an expected expense (GET /travelrequest/v4/expenses/{expenseUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -809,7 +809,7 @@ Get a single expense (GET /expensereports/v4/users/{userId}/context/{contextType | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -887,7 +887,7 @@ Retrieve a single expense report header by id via Expense Report v4 (/expenserep | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -981,7 +981,7 @@ Get expense itemizations (GET /expensereports/v4/users/{userId}/context/{context | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1029,7 +1029,7 @@ Get a single trip/itinerary (GET /api/travel/trip/v1.1/{tripID}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1079,7 +1079,7 @@ Get a single custom list (GET /list/v4/lists/{listId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1115,7 +1115,7 @@ Get a single list item (GET /list/v4/items/{itemId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1149,7 +1149,7 @@ Get a purchase request by ID (GET /purchaserequest/v4/purchaserequests/{id}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1185,7 +1185,7 @@ Get a single receipt by ID (GET /receipts/v4/{receiptId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1217,7 +1217,7 @@ Get receipt processing status (GET /receipts/v4/status/{receiptId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1246,7 +1246,7 @@ Get a travel profile (GET /api/travelprofile/v2.0/profile). Returns the calling | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1297,7 +1297,7 @@ Get a single travel request (GET /travelrequest/v4/requests/{requestUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1407,7 +1407,7 @@ Get a single user by UUID (GET /profile/identity/v4.1/Users/{id}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1433,7 +1433,7 @@ Issue a cash advance (POST /cashadvance/v4/cashadvances/{cashadvanceId}/issue). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1462,7 +1462,7 @@ List allocations on an expense (GET /expensereports/v4/users/{userId}/context/{c | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1489,7 +1489,7 @@ List attendees associated with an expense (GET /expensereports/v4/users/{userId} | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1534,7 +1534,7 @@ List budget categories (GET /budget/v4/budgetCategory). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1557,7 +1557,7 @@ List budget item headers (GET /budget/v4/budgetItemHeader). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1586,7 +1586,7 @@ List exceptions on a report (GET /expensereports/v4/users/{userId}/context/{cont | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1619,7 +1619,7 @@ List expected expenses on a travel request (GET /travelrequest/v4/requests/{requ | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1644,7 +1644,7 @@ List expenses on a report (GET /expensereports/v4/users/{userId}/context/{contex | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1700,7 +1700,7 @@ List expense reports (GET /api/v3.0/expense/reports). Returns a v3 envelope { It | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(us, us2, eu, eu2, cn, emea — defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1762,7 +1762,7 @@ List travel trips/itineraries (GET /api/travel/trip/v1.1). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1824,7 +1824,7 @@ List custom lists (GET /list/v4/lists). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1875,7 +1875,7 @@ List the top-level items (children) for a custom list (GET /list/v4/lists/{listI | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1926,7 +1926,7 @@ List receipts for a user (GET /receipts/v4/users/{userId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1958,7 +1958,7 @@ List comments on a report (GET /expensereports/v4/users/{userId}/context/{contex | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -1998,7 +1998,7 @@ List expense reports awaiting approval (GET /expensereports/v4/users/{userId}/co | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2039,7 +2039,7 @@ Get a single cash advance assigned to a travel request (GET /travelrequest/v4/ca | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2075,7 +2075,7 @@ List travel profile summaries (GET /api/travelprofile/v2.0/summary). LastModifie | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2121,7 +2121,7 @@ List comments on a travel request (GET /travelrequest/v4/requests/{requestUuid}/ | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2151,7 +2151,7 @@ List travel requests (GET /travelrequest/v4/requests). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2230,7 +2230,7 @@ List Concur user identities (GET /profile/identity/v4.1/Users). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2257,7 +2257,7 @@ Move a travel request through workflow (POST /travelrequest/v4/requests/{request | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2298,7 +2298,7 @@ Recall a submitted expense report (PATCH /expensereports/v4/users/{userId}/conte | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2325,7 +2325,7 @@ Remove all attendees from an expense (DELETE /expensereports/v4/users/{userId}/c | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2352,7 +2352,7 @@ Search Concur location reference data (GET /localities/v5/locations). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2408,7 +2408,7 @@ Search users via SCIM .search endpoint (POST /profile/identity/v4.1/Users/.searc | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2432,7 +2432,7 @@ Send back an expense report to the employee (PATCH /expensereports/v4/reports/{r | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2457,7 +2457,7 @@ Submit an expense report into the workflow via Expense Report v4 (PATCH /expense | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2483,7 +2483,7 @@ Update an allocation (PATCH /expensereports/v4/users/{userId}/context/{contextTy | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2511,7 +2511,7 @@ Update an expected expense (PUT /travelrequest/v4/expenses/{expenseUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2552,7 +2552,7 @@ Update an expense (PATCH /expensereports/v4/reports/{reportId}/expenses/{expense | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2578,7 +2578,7 @@ Update an unsubmitted expense report (PATCH /expensereports/v4/users/{userId}/co | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2605,7 +2605,7 @@ Update a list item (PUT /list/v4/items/{itemId}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2640,7 +2640,7 @@ Update a travel request (PUT /travelrequest/v4/requests/{requestUuid}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2715,7 +2715,7 @@ Patch a user identity (PATCH /profile/identity/v4.1/Users/{id}). | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | @@ -2740,7 +2740,7 @@ Upload an image-only receipt (POST /receipts/v4/users/{userId}/image-only-receip | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `datacenter` | string | No | Concur datacenter base URL \(defaults to us.api.concursolutions.com\) | -| `grantType` | string | No | OAuth grant type: client_credentials \(default\), password, refresh_token | +| `grantType` | string | No | OAuth grant type: client_credentials \(default\) or password | | `clientId` | string | Yes | Concur OAuth client ID | | `clientSecret` | string | Yes | Concur OAuth client secret | | `username` | string | No | Username \(only for password grant\) | diff --git a/apps/sim/app/api/tools/sap_concur/shared.ts b/apps/sim/app/api/tools/sap_concur/shared.ts index dd5fd5aa1b..e395b4123a 100644 --- a/apps/sim/app/api/tools/sap_concur/shared.ts +++ b/apps/sim/app/api/tools/sap_concur/shared.ts @@ -22,7 +22,7 @@ export const SapConcurDatacenterSchema = z message: `datacenter must be one of: ${Array.from(SAP_CONCUR_ALLOWED_DATACENTERS).join(', ')}`, }) -export const SapConcurGrantTypeSchema = z.enum(['client_credentials', 'password', 'refresh_token']) +export const SapConcurGrantTypeSchema = z.enum(['client_credentials', 'password']) export const SapConcurAuthSchema = z.object({ datacenter: SapConcurDatacenterSchema.default('us.api.concursolutions.com'), @@ -257,7 +257,12 @@ export async function fetchSapConcurAccessToken( } const geolocation = normalizeGeolocation(data.geolocation, auth.datacenter) - assertSafeExternalUrl(geolocation, 'geolocation') + const geolocationUrl = assertSafeExternalUrl(geolocation, 'geolocation') + if (!SAP_CONCUR_ALLOWED_DATACENTERS.has(geolocationUrl.hostname.toLowerCase())) { + throw new Error( + `Concur geolocation host is not in the allowed datacenter list: ${geolocationUrl.hostname}` + ) + } const expiresInMs = (data.expires_in ?? 3600) * 1000 rememberToken(cacheKey, { diff --git a/apps/sim/blocks/blocks/sap_concur.ts b/apps/sim/blocks/blocks/sap_concur.ts index 54da09b093..b67e2178f4 100644 --- a/apps/sim/blocks/blocks/sap_concur.ts +++ b/apps/sim/blocks/blocks/sap_concur.ts @@ -152,7 +152,7 @@ const BODY_OPS = [ 'sap_concur_update_user', 'sap_concur_search_users', 'sap_concur_create_purchase_request', - 'sap_concur_get_exchange_rate', + 'sap_concur_upload_exchange_rates', ] export const SapConcurBlock: BlockConfig = { @@ -247,7 +247,7 @@ export const SapConcurBlock: BlockConfig = { { label: 'List Budgets', id: 'sap_concur_list_budgets' }, { label: 'Get Budget', id: 'sap_concur_get_budget' }, { label: 'List Budget Categories', id: 'sap_concur_list_budget_categories' }, - { label: 'Get Exchange Rate', id: 'sap_concur_get_exchange_rate' }, + { label: 'Upload Exchange Rates', id: 'sap_concur_upload_exchange_rates' }, { label: 'Create Purchase Request', id: 'sap_concur_create_purchase_request' }, { label: 'Get Purchase Request', id: 'sap_concur_get_purchase_request' }, { label: 'Get Travel Profile', id: 'sap_concur_get_travel_profile' }, @@ -284,7 +284,6 @@ export const SapConcurBlock: BlockConfig = { options: [ { label: 'Client Credentials', id: 'client_credentials' }, { label: 'Password', id: 'password' }, - { label: 'Refresh Token', id: 'refresh_token' }, ], value: () => 'client_credentials', }, @@ -1240,7 +1239,7 @@ export const SapConcurBlock: BlockConfig = { 'sap_concur_update_user', 'sap_concur_search_users', 'sap_concur_create_purchase_request', - 'sap_concur_get_exchange_rate', + 'sap_concur_upload_exchange_rates', 'sap_concur_create_list_item', 'sap_concur_update_list_item', ], @@ -1270,7 +1269,7 @@ export const SapConcurBlock: BlockConfig = { 'sap_concur_get_allocation', 'sap_concur_get_budget', 'sap_concur_get_cash_advance', - 'sap_concur_get_exchange_rate', + 'sap_concur_upload_exchange_rates', 'sap_concur_get_expected_expense', 'sap_concur_get_expense', 'sap_concur_get_expense_report', @@ -1699,7 +1698,7 @@ export const SapConcurBlock: BlockConfig = { return { ...auth, budgetId: params.budgetId } case 'sap_concur_list_budget_categories': return { ...auth } - case 'sap_concur_get_exchange_rate': + case 'sap_concur_upload_exchange_rates': return { ...auth, body: params.body } case 'sap_concur_create_purchase_request': return { ...auth, body: params.body } diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 71601e636e..8da147da4e 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -2292,7 +2292,6 @@ import { getAllocationTool as sapConcurGetAllocationTool, getBudgetTool as sapConcurGetBudgetTool, getCashAdvanceTool as sapConcurGetCashAdvanceTool, - getExchangeRateTool as sapConcurGetExchangeRateTool, getExpectedExpenseTool as sapConcurGetExpectedExpenseTool, getExpenseReportTool as sapConcurGetExpenseReportTool, getExpenseTool as sapConcurGetExpenseTool, @@ -2340,6 +2339,7 @@ import { updateListItemTool as sapConcurUpdateListItemTool, updateTravelRequestTool as sapConcurUpdateTravelRequestTool, updateUserTool as sapConcurUpdateUserTool, + uploadExchangeRatesTool as sapConcurUploadExchangeRatesTool, uploadReceiptImageTool as sapConcurUploadReceiptImageTool, } from '@/tools/sap_concur' import { @@ -5463,7 +5463,7 @@ export const tools: Record = { sap_concur_get_allocation: sapConcurGetAllocationTool, sap_concur_get_budget: sapConcurGetBudgetTool, sap_concur_get_cash_advance: sapConcurGetCashAdvanceTool, - sap_concur_get_exchange_rate: sapConcurGetExchangeRateTool, + sap_concur_upload_exchange_rates: sapConcurUploadExchangeRatesTool, sap_concur_get_expected_expense: sapConcurGetExpectedExpenseTool, sap_concur_get_expense: sapConcurGetExpenseTool, sap_concur_get_expense_report: sapConcurGetExpenseReportTool, diff --git a/apps/sim/tools/sap_concur/approve_expense_report.ts b/apps/sim/tools/sap_concur/approve_expense_report.ts index 5320989be8..9ab472482d 100644 --- a/apps/sim/tools/sap_concur/approve_expense_report.ts +++ b/apps/sim/tools/sap_concur/approve_expense_report.ts @@ -27,7 +27,7 @@ export const approveExpenseReportTool: ToolConfig< type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/associate_attendees.ts b/apps/sim/tools/sap_concur/associate_attendees.ts index c452dce4e0..2efd05707c 100644 --- a/apps/sim/tools/sap_concur/associate_attendees.ts +++ b/apps/sim/tools/sap_concur/associate_attendees.ts @@ -25,7 +25,7 @@ export const associateAttendeesTool: ToolConfig type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/get_cash_advance.ts b/apps/sim/tools/sap_concur/get_cash_advance.ts index 49e0e71f7b..9ef4095859 100644 --- a/apps/sim/tools/sap_concur/get_cash_advance.ts +++ b/apps/sim/tools/sap_concur/get_cash_advance.ts @@ -23,7 +23,7 @@ export const getCashAdvanceTool: ToolConfig = { type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/get_list_item.ts b/apps/sim/tools/sap_concur/get_list_item.ts index 611844a8bb..80ed6af505 100644 --- a/apps/sim/tools/sap_concur/get_list_item.ts +++ b/apps/sim/tools/sap_concur/get_list_item.ts @@ -23,7 +23,7 @@ export const getListItemTool: ToolConfig = { type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/index.ts b/apps/sim/tools/sap_concur/index.ts index 621496eebe..65b26376ef 100644 --- a/apps/sim/tools/sap_concur/index.ts +++ b/apps/sim/tools/sap_concur/index.ts @@ -19,7 +19,6 @@ export { deleteUserTool } from '@/tools/sap_concur/delete_user' export { getAllocationTool } from '@/tools/sap_concur/get_allocation' export { getBudgetTool } from '@/tools/sap_concur/get_budget' export { getCashAdvanceTool } from '@/tools/sap_concur/get_cash_advance' -export { getExchangeRateTool } from '@/tools/sap_concur/get_exchange_rate' export { getExpectedExpenseTool } from '@/tools/sap_concur/get_expected_expense' export { getExpenseTool } from '@/tools/sap_concur/get_expense' export { getExpenseReportTool } from '@/tools/sap_concur/get_expense_report' @@ -67,4 +66,5 @@ export { updateExpenseReportTool } from '@/tools/sap_concur/update_expense_repor export { updateListItemTool } from '@/tools/sap_concur/update_list_item' export { updateTravelRequestTool } from '@/tools/sap_concur/update_travel_request' export { updateUserTool } from '@/tools/sap_concur/update_user' +export { uploadExchangeRatesTool } from '@/tools/sap_concur/upload_exchange_rates' export { uploadReceiptImageTool } from '@/tools/sap_concur/upload_receipt_image' diff --git a/apps/sim/tools/sap_concur/issue_cash_advance.ts b/apps/sim/tools/sap_concur/issue_cash_advance.ts index 527edaf9a7..4e11a53faf 100644 --- a/apps/sim/tools/sap_concur/issue_cash_advance.ts +++ b/apps/sim/tools/sap_concur/issue_cash_advance.ts @@ -23,7 +23,7 @@ export const issueCashAdvanceTool: ToolConfig type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/list_receipts.ts b/apps/sim/tools/sap_concur/list_receipts.ts index 09ed01b302..c33d6c896b 100644 --- a/apps/sim/tools/sap_concur/list_receipts.ts +++ b/apps/sim/tools/sap_concur/list_receipts.ts @@ -23,7 +23,7 @@ export const listReceiptsTool: ToolConfig type: 'string', required: false, visibility: 'user-only', - description: 'OAuth grant type: client_credentials (default), password, refresh_token', + description: 'OAuth grant type: client_credentials (default) or password', }, clientId: { type: 'string', diff --git a/apps/sim/tools/sap_concur/move_travel_request.ts b/apps/sim/tools/sap_concur/move_travel_request.ts index 0e8ed0016c..346fc7dd7a 100644 --- a/apps/sim/tools/sap_concur/move_travel_request.ts +++ b/apps/sim/tools/sap_concur/move_travel_request.ts @@ -24,7 +24,7 @@ export const moveTravelRequestTool: ToolConfig | string } diff --git a/apps/sim/tools/sap_concur/update_allocation.ts b/apps/sim/tools/sap_concur/update_allocation.ts index d5dfeabad7..c7759a430b 100644 --- a/apps/sim/tools/sap_concur/update_allocation.ts +++ b/apps/sim/tools/sap_concur/update_allocation.ts @@ -24,7 +24,7 @@ export const updateAllocationTool: ToolConfig = { - id: 'sap_concur_get_exchange_rate', - name: 'SAP Concur Get Exchange Rate', +export const uploadExchangeRatesTool: ToolConfig< + UploadExchangeRatesParams, + SapConcurProxyResponse +> = { + id: 'sap_concur_upload_exchange_rates', + name: 'SAP Concur Upload Exchange Rates', description: 'Bulk upload up to 100 custom exchange rates (POST /exchangerate/v4/rates). Body: { currency_sets: [{ from_crn_code, to_crn_code, start_date: "YYYY-MM-DD", rate }] }', version: '1.0.0', @@ -23,7 +26,7 @@ export const getExchangeRateTool: ToolConfig