|
| 1 | +# New Document |
| 2 | + |
| 3 | +--- |
| 4 | +ORCHESTRATED GET for User Search |
| 5 | +# |
| 6 | +Draft |
| 7 | +layout: reference |
| 8 | +--- |
| 9 | + |
| 10 | +{EAC Only} |
| 11 | + |
| 12 | +The ORCHESTRATED GET API provides a single, streamlined endpoint that retrieves multiple users identity and spend attributes all at once—eliminating the need to manage multiple integrations. This reduces engineering effort, improves performance, and ensures more consistent data across your workflows. With one unified call, you get faster insights and a simpler, more reliable path to powering your customer experiences. |
| 13 | + |
| 14 | +## <a name="limitations"></a>Limitations |
| 15 | + |
| 16 | +Data Freshness Notice -These APIs are not intended for real-time data retrieval. The data returned may be delayed and should not be expected to reflect live/current state. These endpoints are suitable for use cases that don't require immediate data freshness. |
| 17 | +### <a name="schema-one"></a>Multi-Valued Attribute Limitations |
| 18 | +#### Important Note: |
| 19 | +The following operations are NOT supported within multi-valued attributes: |
| 20 | +#### Unsupported Multi-Valued Examples |
| 21 | +Complex filtering inside multi-valued attributes not supported: |
| 22 | + |
| 23 | +Find users with specific custom field values |
| 24 | + |
| 25 | +```shell |
| 26 | +// NOT SUPPORTED - NOT within multi-valued attribute |
| 27 | +emails[type eq "work" AND NOT (value sw "test.com")] |
| 28 | + |
| 29 | +// NOT SUPPORTED - NE within multi-valued attribute |
| 30 | +emails[type eq "work" AND value ne " [email protected]"] |
| 31 | +``` |
| 32 | +#### Other Limitations |
| 33 | +* Maximum search request payload size is 10 KB |
| 34 | +* Maximum count per request is 1000 |
| 35 | +* The latency of search requests may vary based on filter complexity and result set size |
| 36 | +* The search endpoint does not support sorting of results |
| 37 | +* Due to indexing latency, search data and results may be up to a few minutes behind real-time updates |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +## <a name="products-editions"></a>Products and Editions |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +* Concur Expense Professional Edition |
| 49 | +* Concur Expense Standard Edition |
| 50 | +* Concur Travel Professional Edition |
| 51 | +* Concur Travel Standard Edition |
| 52 | +* Concur Invoice Professional Edition |
| 53 | +* Concur Invoice Standard Edition |
| 54 | +* Concur Request Professional Edition |
| 55 | +* Concur Request Standard Edition |
| 56 | + |
| 57 | +## <a name="scope-usage"></a>Scope Usage |
| 58 | + |
| 59 | + |
| 60 | + |
| 61 | +user.profile.search.read |Read and filter user profiles in Orchestrated GET Search API |
| 62 | + |
| 63 | +## <a name="scope-usage"></a>URI |
| 64 | +```shell |
| 65 | +https://{datacenterURI}/profile/v4/Users/.search |
| 66 | +``` |
| 67 | + |
| 68 | + |
| 69 | +## <a name="access-token-usage"></a>Access Token Usage |
| 70 | + |
| 71 | +All SCIM User Search requests must be using Company JWT authentication with required scope ( user.profile.search.read) and the results are scoped to the company associated with the JWT. |
| 72 | + |
| 73 | + |
| 74 | +## <a name="create-resource"></a>/Users/.search (Retrieve/Filter Users) |
| 75 | + |
| 76 | +Retrieve users by filtering on identity/spend user attributes based on [SCIM RFC 7644](https://datatracker.ietf.org/doc/html/rfc7644) |
| 77 | + |
| 78 | +### Scopes |
| 79 | + |
| 80 | +`user.profile.search.read` - Refer to [Scope Usage](#scope-usage) for full details. |
| 81 | + |
| 82 | +### Supported Extensions |
| 83 | + The following extensions are supported in the search response |
| 84 | + |
| 85 | +```shell |
| 86 | +Core User (urn:ietf:params:scim:schemas:core:2.0:User) |
| 87 | +Enterprise User (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User) |
| 88 | +Spend User (urn:ietf:params:scim:schemas:extension:spend:2.0:User) |
| 89 | +``` |
| 90 | + |
| 91 | +### Filterable Fields |
| 92 | +### <a name="schema-one"></a>Core User Fields |
| 93 | + |
| 94 | +Name|Type|Format|Description |
| 95 | +---|---|---|--- |
| 96 | +id|`string`|-|User UUID |
| 97 | +userName|`string`|-|Login username |
| 98 | +active|`boolean`|-|User active status |
| 99 | +nickName|`string`|-|User nickname |
| 100 | +name.givenName|`string`|-|First name |
| 101 | +name.familyName|`string`|-|Last name |
| 102 | +emails.value|`string, part of multi-valued field`|-|Email address |
| 103 | +emails.type|`string, part of multi-valued field`|-|Email type |
| 104 | +emails.verified|`boolean, part of multi-valued field`|-|Email verification status |
| 105 | +addresses.locality|`string, part of multi-valued field`|-|Address city |
| 106 | +addresses.region|`string, part of multi-valued field`|-|address state/region |
| 107 | +addresses.country|`string, part of multi-valued field`|-|Address country code |
| 108 | +addresses.type|`string, part of multi-valued field`|-|Address type |
| 109 | +meta.created|`dateTime`|-|Creation timestamp |
| 110 | +meta.lastModified|`dateTime`|-|Last modified timestamp |
| 111 | + |
| 112 | +### <a name="schema-one"></a>Enterprise Extension Fields |
| 113 | +Name|Type|Format|Description |
| 114 | +---|---|---|--- |
| 115 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber`|`string`|-|Employee number |
| 116 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:companyId `|`string`|-|Company ID |
| 117 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department`|`string`||Department |
| 118 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:division`|`string`||Division |
| 119 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:startDate`|`dateTime`||Start Date |
| 120 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:costCenter`|`string`||Cost Center |
| 121 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.value`|`string`||Manager UUID |
| 122 | +`urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:terminationDate`|`dateTime`||Termination Date |
| 123 | + |
| 124 | +### <a name="schema-one"></a>Spend User Extension Fields |
| 125 | +Name|Type|Format|Description |
| 126 | +---|---|---|--- |
| 127 | +`urn:ietf:params:scim:schemas:extension:spend:2.0:User:country`|`string`|-|Spend Country Code |
| 128 | +`urn:ietf:params:scim:schemas:extension:spend:2.0:User:customData.id `|`string, part of multi-valued field)`|-|Custom Field ID |
| 129 | +`urn:ietf:params:scim:schemas:extension:spend:2.0:User:customData.value`|`string, part of multi-valued field`||Custom Field value |
| 130 | +`urn:ietf:params:scim:schemas:extension:spend:2.0:User:customData.syncGuid`|`string, part of multi-valued field`||Custom field sync GUID |
| 131 | + |
| 132 | +### Payloads |
| 133 | + |
| 134 | +### Examples |
| 135 | + |
| 136 | +#### Sample Request |
| 137 | + |
| 138 | + |
| 139 | + |
| 140 | +```shell |
| 141 | +curl -X POST "https://us.api.concursolutions.com/profile/v4/Users/.search" \ |
| 142 | + -H "Authorization: Bearer {your_jwt_token}" \ |
| 143 | + -H "Content-Type: application/scim+json" \ |
| 144 | +{ |
| 145 | + "schemas": [ |
| 146 | + "urn:ietf:params:scim:api:messages:2.0:SearchRequest" |
| 147 | + ], |
| 148 | + "filter": "userName eq \" [email protected]\"", |
| 149 | + "attributes": ["name", "emails", "userName"], |
| 150 | + "excludedAttributes": [], |
| 151 | + "count": 10, |
| 152 | + "cursor": null |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +#### Sample Response |
| 157 | + |
| 158 | + |
| 159 | +```shell |
| 160 | +{ |
| 161 | + "schemas": [ |
| 162 | + "urn:ietf:params:scim:api:messages:2.0:ListResponse" |
| 163 | + ], |
| 164 | + "total": 1, |
| 165 | + "itemsPerPage": 1, |
| 166 | + "Resources": [ |
| 167 | + { |
| 168 | + "emails": [ |
| 169 | + { |
| 170 | + "type": "work", |
| 171 | + |
| 172 | + "verified": false |
| 173 | + }, |
| 174 | + { |
| 175 | + "type": "home", |
| 176 | + |
| 177 | + "verified": false |
| 178 | + } |
| 179 | + ], |
| 180 | + |
| 181 | + "id": "1f3124bf-f147-499b-9557-3d7672173de3", |
| 182 | + "name": { |
| 183 | + "givenName": "Blah", |
| 184 | + "honorificPrefix": "Mr", |
| 185 | + "familyName": "Smith" |
| 186 | + } |
| 187 | + } |
| 188 | + ] |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +## <a name="schema"></a>Pagination |
| 193 | +The SCIM User Search endpoint supports [cursor-based pagination](https://datatracker.ietf.org/doc/rfc9865/) . Use the count parameter to specify the number of results per page and the cursor parameter to navigate through pages. |
| 194 | + |
| 195 | +### <a name="schema-one"></a>SCIM Filter Operators |
| 196 | + |
| 197 | +#### Comparison Operators |
| 198 | + |
| 199 | +Operator Name|Operator Description| |
| 200 | +---|--- |
| 201 | +`eq`|`Equal to`|-|User UUID |
| 202 | +`ne`|`Not equal to`|-|Login username |
| 203 | +`co`|`Contains substring`||User active status |
| 204 | +`sw`|`Starts with`||User nickname |
| 205 | +`ew`|`Ends with`||First name |
| 206 | +`pr`|`Present ( attribute has a value)`||Last name |
| 207 | +`gt`|`Greater than`||Email address |
| 208 | +`ge`|`Greater than or equal to`||Email type |
| 209 | +`lt`|`Less than`|| Email verification status |
| 210 | +`le`|`Less than or equal to`||Address city |
| 211 | + |
| 212 | + |
| 213 | +#### Logical Operators |
| 214 | + |
| 215 | +Operator Name|Operator Description| |
| 216 | +---|--- |
| 217 | +`and`|` Logical AND (All combined expressions must be true)`|-| |
| 218 | +`or`|`Logical OR (At least one combined expression must be true)` |
| 219 | +`not`|`Logical NOT (The expression is true if the filtered expression is false)` |
| 220 | +` |
| 221 | + |
| 222 | +### <a name="schema-one"></a>Use Cases by operator |
| 223 | +#### 1. Equal To (eq) |
| 224 | +Find users with a specific username |
| 225 | + |
| 226 | +```shell |
| 227 | +"userName eq \" [email protected]\"" |
| 228 | + |
| 229 | +``` |
| 230 | +Find active users only |
| 231 | +```shell |
| 232 | +"active eq true" |
| 233 | + |
| 234 | +``` |
| 235 | +Find users with verified work email |
| 236 | +```shell |
| 237 | +""emails[type eq \"work\" and verified eq true]"" |
| 238 | + |
| 239 | +``` |
| 240 | +#### 2. Not Equal To (ne) |
| 241 | + |
| 242 | +Find users not in a specific department |
| 243 | +```shell |
| 244 | +""urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department ne \"Sales\"" |
| 245 | + |
| 246 | +``` |
| 247 | +Find inactive users |
| 248 | +```shell |
| 249 | +""active ne true"" |
| 250 | + |
| 251 | +``` |
| 252 | +#### 3. Contains (co) |
| 253 | + |
| 254 | +Find users with names containing specific substring |
| 255 | +```shell |
| 256 | +"name.givenName co \"John\"" |
| 257 | +``` |
| 258 | +Find users with work email addresses containing domain |
| 259 | +```shell |
| 260 | +"emails[type eq \"work\" and value co \"@company.com\"]" |
| 261 | + |
| 262 | +``` |
| 263 | + |
| 264 | +#### 4. Starts With (sw) |
| 265 | + |
| 266 | +Find users with last names starting with "A" |
| 267 | +```shell |
| 268 | +"name.familyName sw \"A\"" |
| 269 | +``` |
| 270 | + |
| 271 | +#### 5. Ends With (ew) |
| 272 | + |
| 273 | +Find users with email addresses ending with specific domain |
| 274 | +```shell |
| 275 | +"emails.value ew \"@company.com\"" |
| 276 | +"emails[value ew \"@company.com\"] |
| 277 | +``` |
| 278 | +Find users with work email addresses ending with specific domain |
| 279 | +```shell |
| 280 | +"emails[type eq \"work\" and value ew \"@company.com\"]" |
| 281 | +``` |
| 282 | +#### 6. Present (pr) |
| 283 | + |
| 284 | +Find users who have a nickname defined |
| 285 | +```shell |
| 286 | +"nickName pr" |
| 287 | +``` |
| 288 | +Find users with manager assigned |
| 289 | +```shell |
| 290 | +"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.value pr" |
| 291 | +``` |
| 292 | +#### 7. Greater Than (gt) |
| 293 | + |
| 294 | +Find users updated after specific date |
| 295 | +```shell |
| 296 | +"meta.lastModified gt \"2025-01-01T00:00:00Z\"" |
| 297 | +``` |
| 298 | +#### 8. Greater Than or Equal (ge) |
| 299 | + |
| 300 | +Find users created on or after specific date |
| 301 | +```shell |
| 302 | +"meta.created ge \"2025-01-01T00:00:00Z\"" |
| 303 | +``` |
| 304 | +#### 9. Less Than (lt) |
| 305 | + |
| 306 | +Find users created before specific date |
| 307 | + |
| 308 | +```shell |
| 309 | +"meta.created lt \"2025-01-31T23:59:59Z\"" |
| 310 | +``` |
| 311 | +Find users with start date before specific date |
| 312 | +```shell |
| 313 | +"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:startDate lt \"2025-01-31T23:59:59Z\"" |
| 314 | +``` |
| 315 | + |
| 316 | +#### 10 .Less Than or Equal (le) |
| 317 | + |
| 318 | +Find users last modified on or before specific date |
| 319 | +```shell |
| 320 | +"meta.lastModified le \"2025-01-31T23:59:59Z\"" |
| 321 | +``` |
| 322 | + |
| 323 | +### <a name="schema-one"></a>Complex Logical Operations |
| 324 | +#### AND Operations |
| 325 | + |
| 326 | +Find active users in specific department |
| 327 | + |
| 328 | +```shell |
| 329 | +"active eq true and urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department eq \"Sales\"" |
| 330 | +``` |
| 331 | +Find users created within date range |
| 332 | +```shell |
| 333 | +"meta.created ge \"2023-01-01T00:00:00Z\" and meta.created le \"2023-12-31T23:59:59Z\"" |
| 334 | +``` |
| 335 | +#### OR Operations |
| 336 | + |
| 337 | +Find users in multiple departments |
| 338 | + |
| 339 | +```shell |
| 340 | +"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department eq \"Engineering\" or urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department eq \"Marketing\"" |
| 341 | +``` |
| 342 | +Find users in multiple countries |
| 343 | +```shell |
| 344 | +"urn:ietf:params:scim:schemas:extension:spend:2.0:User:country eq \"US\" or urn:ietf:params:scim:schemas:extension:spend:2.0:User:country eq \"CA\"" |
| 345 | +``` |
| 346 | +Find users with work or home addresses in specific city |
| 347 | +```shell |
| 348 | +"addresses[type eq \"work\" and locality eq \"Seattle\"] or addresses[type eq \"home\" and locality eq \"Seattle\"]" |
| 349 | +``` |
| 350 | +#### NOT Operations |
| 351 | + |
| 352 | +Find users not in a specific department |
| 353 | + |
| 354 | +```shell |
| 355 | +"not (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department eq \"Contractors\")" |
| 356 | +``` |
| 357 | +Find users without termination date |
| 358 | +```shell |
| 359 | +"not (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:terminationDate pr)" |
| 360 | +``` |
| 361 | +Find users contain work email but not home email |
| 362 | +```shell |
| 363 | +"emails[type eq \"work\"] and NOT (emails[type eq \"home\"])" |
| 364 | +``` |
| 365 | +### <a name="schema-one"></a>Complex Multi-Attribute Scenarios |
| 366 | +#### Employee Search Scenarios |
| 367 | + |
| 368 | +Find users with specific custom field values |
| 369 | + |
| 370 | +```shell |
| 371 | +"urn:ietf:params:scim:schemas:extension:spend:2.0:User:customData[id eq \"custom1\" and value eq \"VIP\"]" |
| 372 | +``` |
| 373 | +Find users with verified work emails from specific domain |
| 374 | +```shell |
| 375 | +"emails[type eq \"work\" and verified eq true and value ew \"@company.com\"]" |
| 376 | +``` |
| 377 | + |
| 378 | + |
| 379 | + |
| 380 | +### <a name="schema-error"></a>Error Sample |
| 381 | + |
| 382 | +```shell |
| 383 | +{ |
| 384 | + "schemas": [ |
| 385 | + "urn:ietf:params:scim:api:messages:2.0:Error", |
| 386 | + "urn:ietf:params:scim:api:messages:concur:2.0:Error" |
| 387 | + ], |
| 388 | + "status": "400", |
| 389 | + "urn:ietf:params:scim:api:messages:concur:2.0:Error": { |
| 390 | + "messages": [ |
| 391 | + { |
| 392 | + "code": "INVALID_INPUT", |
| 393 | + "message": "Invalid attribute path [:test]", |
| 394 | + "type": "error" |
| 395 | + } |
| 396 | + ] |
| 397 | + } |
| 398 | +} |
| 399 | +``` |
0 commit comments