@celigo/api-specs 0.2.170 → 0.2.172

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,9 @@ info:
9
9
  (`GET`/`PUT /v1/mft/fileserver`) and the partner accounts that log in to it
10
10
  (`/v1/mft/fileserver/accounts`), each chrooted to a Celigo Storage folder. Requires a
11
11
  full-access API token — folder-path-scoped and other restricted tokens answer 403
12
- FILESERVER_FULL_ACCESS_TOKEN_REQUIRED on every route.
12
+ FILESERVER_FULL_ACCESS_TOKEN_REQUIRED on every route, and so does every personal access
13
+ token, whatever its creator's role. Only the account owner and administrators may manage
14
+ the server.
13
15
  servers:
14
16
  - url: https://api.integrator.io
15
17
  description: Production (US / default region)
@@ -24,7 +26,7 @@ security:
24
26
  tags:
25
27
  - name: File Server
26
28
  description: |-
27
- Each environment can run a Celigo-hosted SFTP file server. Enabling it claims a permanent `identifier` that becomes part of every partner login (`<username>@<identifier>`) and exposes the shared endpoint and host-key fingerprints partners need to connect. Partner accounts are created under the server, each with its own password and a Celigo Storage folder that becomes the account's root, so files a partner uploads appear in that folder and files placed there are what the partner can download. The account's license must include the file server add-on (`fileserver.enabled`), and every call needs a full-access API token.
29
+ Each environment can run a Celigo-hosted SFTP file server. Enabling it claims a permanent `identifier` that becomes part of every partner login (`<username>@<identifier>`) and exposes the shared endpoint and host-key fingerprints partners need to connect. Partner accounts are created under the server, each with its own password and a Celigo Storage folder that becomes the account's root, so files a partner uploads appear in that folder and files placed there are what the partner can download. The account's license must include the file server add-on (`fileserver.enabled`), and every call needs a full-access API token: scoped tokens and personal access tokens are refused, and so are manage, monitor and integration-level users.
28
30
 
29
31
  ## File server and account schemas
30
32
 
@@ -87,7 +89,11 @@ paths:
87
89
  '401':
88
90
  $ref: '#/components/responses/401-unauthorized'
89
91
  '403':
90
- description: The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`).
92
+ description: |-
93
+ The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`). A
94
+ personal access token is refused the same way as a scoped token, and a manage, monitor
95
+ or integration-level user gets `access_restricted`: only the owner and administrators
96
+ manage the file server.
91
97
  content:
92
98
  application/json:
93
99
  schema:
@@ -98,6 +104,12 @@ paths:
98
104
  errors:
99
105
  - code: FILESERVER_FULL_ACCESS_TOKEN_REQUIRED
100
106
  message: The file server management APIs require an API token with full access
107
+ notAdministrator:
108
+ summary: A manage, monitor or integration-level user
109
+ value:
110
+ errors:
111
+ - code: access_restricted
112
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
101
113
  '404':
102
114
  description: The environment is entitled but its server has never been enabled (`FILESERVER_NOT_FOUND`).
103
115
  content:
@@ -220,7 +232,7 @@ paths:
220
232
  description: |-
221
233
  The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`),
222
234
  the account's license lacks the file server add-on or the environment is a
223
- sandbox (`FILESERVER_NOT_ENTITLED`).
235
+ sandbox (`FILESERVER_NOT_ENTITLED`). A personal access token is refused the same way as a scoped token, and a manage, monitor or integration-level user gets `access_restricted`: only the owner and administrators manage the file server.
224
236
  content:
225
237
  application/json:
226
238
  schema:
@@ -231,6 +243,12 @@ paths:
231
243
  errors:
232
244
  - code: FILESERVER_NOT_ENTITLED
233
245
  message: The file server add-on is not enabled for this account
246
+ notAdministrator:
247
+ summary: A manage, monitor or integration-level user
248
+ value:
249
+ errors:
250
+ - code: access_restricted
251
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
234
252
  '404':
235
253
  description: A disable was sent for an environment whose server was never enabled (`FILESERVER_NOT_FOUND`).
236
254
  content:
@@ -396,7 +414,11 @@ paths:
396
414
  '401':
397
415
  $ref: '#/components/responses/401-unauthorized'
398
416
  '403':
399
- description: The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`), or the environment is a sandbox (`FILESERVER_NOT_ENTITLED`).
417
+ description: |-
418
+ The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`), or
419
+ the environment is a sandbox (`FILESERVER_NOT_ENTITLED`). A personal access token is
420
+ refused the same way as a scoped token, and a manage, monitor or integration-level user
421
+ gets `access_restricted`: only the owner and administrators manage the file server.
400
422
  content:
401
423
  application/json:
402
424
  schema:
@@ -407,6 +429,12 @@ paths:
407
429
  errors:
408
430
  - code: FILESERVER_FULL_ACCESS_TOKEN_REQUIRED
409
431
  message: The file server management APIs require an API token with full access
432
+ notAdministrator:
433
+ summary: A manage, monitor or integration-level user
434
+ value:
435
+ errors:
436
+ - code: access_restricted
437
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
410
438
  '422':
411
439
  description: The environment's server has never been enabled (`FILESERVER_NOT_ENABLED`); a disabled server is still manageable.
412
440
  content:
@@ -487,7 +515,7 @@ paths:
487
515
  The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`);
488
516
  the license lacks the add-on or the environment is a sandbox
489
517
  (`FILESERVER_NOT_ENTITLED`); or the environment already holds
490
- `limits.maxAccounts` enabled accounts (`FILESERVER_MAX_ACCOUNTS_EXCEEDED`).
518
+ `limits.maxAccounts` enabled accounts (`FILESERVER_MAX_ACCOUNTS_EXCEEDED`). A personal access token is refused the same way as a scoped token, and a manage, monitor or integration-level user gets `access_restricted`: only the owner and administrators manage the file server.
491
519
  content:
492
520
  application/json:
493
521
  schema:
@@ -498,6 +526,12 @@ paths:
498
526
  errors:
499
527
  - code: FILESERVER_MAX_ACCOUNTS_EXCEEDED
500
528
  message: The maximum number of enabled accounts for this environment has been reached
529
+ notAdministrator:
530
+ summary: A manage, monitor or integration-level user
531
+ value:
532
+ errors:
533
+ - code: access_restricted
534
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
501
535
  '409':
502
536
  description: Another account in this environment already has that username, enabled or not (`FILESERVER_USERNAME_TAKEN`).
503
537
  content:
@@ -688,7 +722,7 @@ paths:
688
722
  The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`);
689
723
  the license lacks the add-on or the environment is a sandbox
690
724
  (`FILESERVER_NOT_ENTITLED`); or re-enabling would exceed `limits.maxAccounts`
691
- (`FILESERVER_MAX_ACCOUNTS_EXCEEDED`).
725
+ (`FILESERVER_MAX_ACCOUNTS_EXCEEDED`). A personal access token is refused the same way as a scoped token, and a manage, monitor or integration-level user gets `access_restricted`: only the owner and administrators manage the file server.
692
726
  content:
693
727
  application/json:
694
728
  schema:
@@ -699,6 +733,12 @@ paths:
699
733
  errors:
700
734
  - code: FILESERVER_MAX_ACCOUNTS_EXCEEDED
701
735
  message: The maximum number of enabled accounts for this environment has been reached
736
+ notAdministrator:
737
+ summary: A manage, monitor or integration-level user
738
+ value:
739
+ errors:
740
+ - code: access_restricted
741
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
702
742
  '404':
703
743
  $ref: '#/components/responses/404-account-not-found'
704
744
  '409':
@@ -1407,7 +1447,12 @@ components:
1407
1447
  value:
1408
1448
  message: Bearer Authentication Failed
1409
1449
  403-full-access-required:
1410
- description: The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`), or the license lacks the add-on / the environment is a sandbox (`FILESERVER_NOT_ENTITLED`).
1450
+ description: |-
1451
+ The token is not a full-access API token (`FILESERVER_FULL_ACCESS_TOKEN_REQUIRED`) --
1452
+ a scoped API token, or any personal access token, which never counts as full access --
1453
+ or the license lacks the add-on / the environment is a sandbox (`FILESERVER_NOT_ENTITLED`).
1454
+ A manage, monitor or integration-level user is refused with `access_restricted`: only the
1455
+ account owner and administrators manage the file server.
1411
1456
  content:
1412
1457
  application/json:
1413
1458
  schema:
@@ -1418,6 +1463,12 @@ components:
1418
1463
  errors:
1419
1464
  - code: FILESERVER_FULL_ACCESS_TOKEN_REQUIRED
1420
1465
  message: The file server management APIs require an API token with full access
1466
+ notAdministrator:
1467
+ summary: A manage, monitor or integration-level user
1468
+ value:
1469
+ errors:
1470
+ - code: access_restricted
1471
+ message: The role which you are associated with doesn't have the required permissions to perform the action.
1421
1472
  404-account-not-found:
1422
1473
  description: No account with this id in the caller's environment, or the id is not a valid identifier (`FILESERVER_ACCOUNT_NOT_FOUND`).
1423
1474
  content:
package/dist/flow.yml CHANGED
@@ -5523,6 +5523,17 @@ components:
5523
5523
  into a schedule (for example all wildcards, `? * * ? * *`), `422
5524
5524
  schedule_not_supported` when its runs would be less than a minute apart — which
5525
5525
  is also what free text such as `every 5 minutes` produces.
5526
+
5527
+ A save can store a later minute than it was sent. A minute field that is 0, 15,
5528
+ 30 or 45, a list made only of those minutes, a range that starts at minute 0, or a
5529
+ `*/N` step with N above 5 is stored 5 minutes later: `? 0 6 ? * *` as
5530
+ `? 5 6 ? * *`, `? 0,15,30,45 * ? * *` as `? 5,20,35,50 * ? * *`, `? 0-10 * ? * *`
5531
+ as `? 5-15 * ? * *`, and `? */15 * ? * *` as `? 5-59/15 * ? * *`. Any other minute
5532
+ field is kept as sent, including `? */5 * * * *` and lists that mix in other
5533
+ minutes (`? 0,10,20,30,40,50 * ? * *`), and the other fields never change. POST,
5534
+ PUT and PATCH all store it this way, the response and later reads return the
5535
+ stored value, and scheduled runs start at the stored minutes, so a flow saved for
5536
+ 06:00 runs at 06:05 (live-verified 2026-10-22).
5526
5537
  x-celigo-ai-guidance:
5527
5538
  - |-
5528
5539
  Build `schedule` as a Celigo 6-field cron:
@@ -5544,20 +5555,22 @@ components:
5544
5555
  schedule (`? * * ? * *`) with 422 `invalid_value`. Fix or clear the schedule
5545
5556
  instead of disabling the flow to get past the error.
5546
5557
  - |-
5547
- Prefer explicit lists when AUTHORING a schedule — hourly or longer:
5548
- minute `5` with an explicit hour list
5558
+ When AUTHORING a schedule, read `schedule` back after the save and give
5559
+ the user the stored times, not the requested ones: a schedule written
5560
+ for minute 0, 15, 30 or 45 can be stored, and run, 5 minutes later (see
5561
+ the description), and an explicit list is moved the same way as a step
5562
+ form. Hourly or longer: minute `5` with an explicit hour list
5549
5563
  (`? 5 0,4,8,12,16,20 ? * *` = every 4 hours;
5550
- `? 5 9 ? * 1,2,3,4,5` = weekdays 9 AM; `? 5 0 ? * *` = daily);
5551
- sub-hourly: an explicit minute list with hour `*`
5552
- (`? 0,15,30,45 * ? * *` = every 15 minutes). Lists match the UI's
5553
- schedule builder and make fire times unambiguous — the scheduler can
5554
- offset step expressions (the UI's sub-hourly presets fire at minutes
5555
- 10/25/40/55).
5564
+ `? 5 9 ? * 1,2,3,4,5` = weekdays 9:05 AM; `? 5 0 ? * *` = daily at
5565
+ 00:05); sub-hourly: an explicit minute list with hour `*`
5566
+ (`? 5,20,35,50 * ? * *` = every 15 minutes) or a step form.
5556
5567
  - |-
5557
5568
  Wildcard/step/range forms (`? */5 * * * *`, `? 10-59/30 * * * *`) are
5558
5569
  valid and the scheduler runs them — never claim an existing schedule's
5559
5570
  format is invalid or the cause of missed runs, and never rewrite a
5560
- working schedule into a different format as a fix. A new scheduled
5571
+ working schedule into a different format as a fix. A minute stored 5
5572
+ minutes after the one written is the save's normal behavior, not a
5573
+ fault, and a rewritten schedule is stored the same way. A new scheduled
5561
5574
  instance is not started while a previous run of the flow is still in
5562
5575
  progress (boundaries skipped during a long run are by design); missed
5563
5576
  runs on an enabled, unchanged flow with nothing running are a
@@ -6692,6 +6705,7 @@ components:
6692
6705
  x-celigo-ai-guidance:
6693
6706
  - Read the classification off the record; never infer it from the message text — the classifier is heuristic and identical messages can classify differently.
6694
6707
  - There is no setting, mapping, hook, or API that changes a classification; a wrong one is a Celigo Support matter.
6708
+ - '`parse` also covers a request URL template that names a field the record lacks (`handlebars_template_parse_error`, `Failed to generate request url from template: … Details: "<field>" not defined in the model.`). That is missing data, not template syntax: nothing was sent, a retry of the same record fails the same way, and the fix is the record or how the import routes it (see an HTTP import''s `relativeURI`).'
6695
6709
  classifiedBy:
6696
6710
  type: string
6697
6711
  description: '`auto` on every classified error; absent on unclassified ones.'
@@ -7364,7 +7378,11 @@ components:
7364
7378
  type: integer
7365
7379
  readOnly: true
7366
7380
  description: |-
7367
- Number of records skipped, for example by an import's ignore-existing or ignore-missing rule.
7381
+ Number of records skipped, by a filter or by an import's ignore-existing or ignore-missing
7382
+ rule. Records an import's filter skips count in that import's child job; records an export's
7383
+ output filter drops count in the export's child job, whose `numSuccess` then counts only the
7384
+ records that passed (an export that read 6 records and dropped 3 reads `numSuccess` 3,
7385
+ `numIgnore` 3; live-verified 2026-10-22). Filtered records raise no error.
7368
7386
  Summed across steps on a parent flow job; per step on a child job.
7369
7387
  examples:
7370
7388
  - 0
@@ -8072,16 +8090,18 @@ components:
8072
8090
  description: |-
8073
8091
  Execution stage whose data to return. `apiCall` holds the request and response an HTTP
8074
8092
  export or import sent. On a job whose `logMode` is `debug`, an export's transform and
8075
- output filter record under `transformation` and `outputFilter`, an import's mapping and
8076
- response mapping under `mapping` and `responseMapping`, and a script hook's `options` and
8093
+ output filter record under `transformation` and `outputFilter`, an import's filter (its
8094
+ `filter` field) under `inputFilter`, an import's mapping and response mapping under
8095
+ `mapping` and `responseMapping`, and a script hook's `options` and
8077
8096
  return value under its hook type plus `Hook` (`preSavePageHook`, `preMapHook`,
8078
8097
  `postMapHook`, `postSubmitHook`, `postResponseMapHook`), whatever the function is called;
8079
8098
  neither the bare hook name (`preMap`) nor `<functionName>Hook` returns them (live-verified
8080
- 2026-10-20).
8099
+ 2026-10-20; `inputFilter` 2026-10-22).
8081
8100
  examples:
8082
8101
  - apiCall
8083
8102
  - transformation
8084
8103
  - outputFilter
8104
+ - inputFilter
8085
8105
  - mapping
8086
8106
  - responseMapping
8087
8107
  - preSavePageHook
@@ -8114,8 +8134,11 @@ components:
8114
8134
 
8115
8135
  - `apiCall`: the request's method and URI and the response's status code. A job whose `logMode` is
8116
8136
  `detailed` or `debug` also records each side's headers and body; a `basic` job does not.
8117
- - `mapping`, `transformation`, `outputFilter`, `responseMapping`: a per-record entry carrying the
8118
- record's `recordId`, the stage's `input`, and its `output` (`outputFilter` has `success` instead).
8137
+ - `mapping`, `transformation`, `outputFilter`, `inputFilter`, `responseMapping`: a per-record entry
8138
+ carrying the record's `recordId`, the stage's `input`, and its `output`. The filter stages
8139
+ (`outputFilter` for an export's output filter, `inputFilter` for an import's filter) have
8140
+ `success` instead, `false` for a record the filter dropped (`inputFilter` live-verified
8141
+ 2026-10-22).
8119
8142
  - `preSavePageHook`, `preMapHook`, `postMapHook`, `postSubmitHook`: one entry for the record's whole
8120
8143
  group, with no `recordId`. `input` is a one-element array holding the `options` the hook received,
8121
8144
  and `output` holds what the hook returned.
@@ -594,9 +594,9 @@ components:
594
594
  LLM configuration for an `ai_agent` guardrail — which provider and model evaluate each
595
595
  record, with instructions, parameter tuning, and output format. Guardrails never invoke
596
596
  tools, so unlike an AI agent import no block here accepts a `tools` array. MCP `prompts`
597
- and `resources` are accepted on save, but an unreachable MCP server doesn't fail the
598
- run (verified on OpenAI), so put the policy the guardrail must apply in its
599
- instructions. Providers come in two families with two configuration formats:
597
+ and `resources` are accepted on save but never used at run time, so put the policy the
598
+ guardrail must apply in its instructions. Providers come in two families with two
599
+ configuration formats:
600
600
 
601
601
  - **Built-in providers** — each has its own configuration block.
602
602
  - **openai**: OpenAI models (GPT-4.1, GPT-5, etc.). Configure via the `openai` object.
@@ -761,7 +761,7 @@ components:
761
761
  type: array
762
762
  description: |-
763
763
  MCP prompt entries saved with a catalog-provider guardrail (generic flat format).
764
- Each entry references one MCP connection and the prompt names allowed from it.
764
+ Each entry references one MCP connection and prompt names; a guardrail's run never fetches them.
765
765
  items:
766
766
  type: object
767
767
  properties:
@@ -782,7 +782,7 @@ components:
782
782
  description: Connection to the MCP server that exposes the prompts.
783
783
  allowedPrompts:
784
784
  type: array
785
- description: Prompt names the model may fetch from the server.
785
+ description: Prompt names saved with the entry; a guardrail's run never fetches them.
786
786
  items:
787
787
  type: string
788
788
  x-celigo-ai-guidance:
@@ -1039,7 +1039,7 @@ components:
1039
1039
  type: array
1040
1040
  description: |-
1041
1041
  MCP prompt entries saved with the guardrail. Each item references one
1042
- MCP connection and the prompt names allowed from it.
1042
+ MCP connection and prompt names; a guardrail's run never fetches them.
1043
1043
  items:
1044
1044
  type: object
1045
1045
  properties:
@@ -1061,7 +1061,7 @@ components:
1061
1061
  description: Connection to the MCP server.
1062
1062
  allowedPrompts:
1063
1063
  type: array
1064
- description: Prompt names to allow from the MCP server.
1064
+ description: Prompt names saved with the entry; a guardrail's run never fetches them.
1065
1065
  items:
1066
1066
  type: string
1067
1067
  resources:
@@ -1228,7 +1228,7 @@ components:
1228
1228
  type: array
1229
1229
  description: |-
1230
1230
  MCP prompt entries saved with a Gemini guardrail. Each item references one
1231
- MCP connection and the prompt names allowed from it.
1231
+ MCP connection and prompt names; a guardrail's run never fetches them.
1232
1232
  items:
1233
1233
  type: object
1234
1234
  properties:
@@ -1250,7 +1250,7 @@ components:
1250
1250
  description: Connection to the MCP server.
1251
1251
  allowedPrompts:
1252
1252
  type: array
1253
- description: Prompt names to allow from the MCP server.
1253
+ description: Prompt names saved with the entry; a guardrail's run never fetches them.
1254
1254
  items:
1255
1255
  type: string
1256
1256
  resources:
@@ -1450,7 +1450,7 @@ components:
1450
1450
  type: array
1451
1451
  description: |-
1452
1452
  MCP prompt entries saved with a Claude guardrail. Each item references one
1453
- MCP connection and the prompt names allowed from it.
1453
+ MCP connection and prompt names; a guardrail's run never fetches them.
1454
1454
  items:
1455
1455
  type: object
1456
1456
  properties:
@@ -1472,7 +1472,7 @@ components:
1472
1472
  description: Connection to the MCP server.
1473
1473
  allowedPrompts:
1474
1474
  type: array
1475
- description: Prompt names to allow from the MCP server.
1475
+ description: Prompt names saved with the entry; a guardrail's run never fetches them.
1476
1476
  items:
1477
1477
  type: string
1478
1478
  resources:
@@ -1544,10 +1544,9 @@ components:
1544
1544
  (`aiAgent.tools`, `aiAgent.openai.tools`, `aiAgent.litellm._overrides.gemini.tools`,
1545
1545
  `aiAgent.litellm._overrides.anthropic.tools`) fails the save with 422
1546
1546
  `guardrail_tools_not_allowed`. MCP `prompts` and `resources` are still accepted on
1547
- save, but don't rely on them for the check: with their MCP server unreachable, a
1548
- guardrail runs on its instructions and input alone, with no error, where an AI agent's
1549
- run fails (verified on OpenAI). Put the policy the guardrail must apply in its
1550
- instructions.
1547
+ save, but a guardrail's run never uses them: it gives the model only its instructions
1548
+ and input, whether the MCP server can be reached or not. Put the policy the guardrail
1549
+ must apply in its instructions.
1551
1550
  properties:
1552
1551
  type:
1553
1552
  type: string
@@ -1941,8 +1940,10 @@ components:
1941
1940
  - A dot path from the record root (e.g. `email`, `address.city`), read from the
1942
1941
  incoming record. A path that matches no field writes nothing.
1943
1942
  - Handlebars template (contains `{{`) for concatenation /
1944
- formatting / conditional logic (e.g.
1945
- `{{record.firstName}} {{record.lastName}}`).
1943
+ formatting / conditional logic (e.g. `{{firstName}} {{lastName}}`,
1944
+ `{{#if mobile}}{{mobile}}{{else}}{{phone}}{{/if}}`). The template reads the
1945
+ record's fields by bare name: `{{record.firstName}}` and `{{data.firstName}}`
1946
+ render nothing, so the field is left out even when the record has the value.
1946
1947
 
1947
1948
  A `$.` JSONPath (the Mapper 2.0 `mappings` syntax) reads nothing here, and a bare
1948
1949
  string is read as a field path, not a constant: set constants in `hardCodedValue`.
@@ -1983,8 +1984,9 @@ components:
1983
1984
  x-celigo-ai-guidance:
1984
1985
  - |-
1985
1986
  When true, skip this field entirely when ``extract`` / lookup
1986
- produces empty / null. Without this flag the destination field
1987
- receives null and may overwrite existing data.
1987
+ produces an empty string, null or nothing. Without this flag an
1988
+ empty string is written as ``""`` and null as null, either of which
1989
+ may overwrite existing data; a missing source is left out either way.
1988
1990
  immutable:
1989
1991
  type: boolean
1990
1992
  description: When true, the mapped value cannot be overwritten by later mapping steps.
@@ -2001,7 +2003,15 @@ components:
2001
2003
  type:
2002
2004
  - string
2003
2005
  - 'null'
2004
- description: Fallback value used when the extract yields no value.
2006
+ description: |-
2007
+ Fallback value written when the source value is an empty string, null or
2008
+ missing. Without a default, an empty string and null are written as they are
2009
+ and a missing field is left out.
2010
+ x-celigo-ai-guidance:
2011
+ - |-
2012
+ Use ``default``, not ``hardCodedValue``, for a fallback on a field that is
2013
+ sometimes empty: ``hardCodedValue`` is written on every record and replaces
2014
+ the values that exist.
2005
2015
  extractDateFormat:
2006
2016
  type: string
2007
2017
  description: Date format of the source value, used to parse it before conversion.
@@ -2177,7 +2187,8 @@ components:
2177
2187
  mapping:
2178
2188
  type: object
2179
2189
  description: |-
2180
- Mapper 1.0 input mapping that selects the field evaluated as `text`.
2190
+ Mapper 1.0 input mapping that selects what is evaluated: a field mapped
2191
+ to `text`, or an object mapped to `record` (evaluated as its JSON).
2181
2192
  Served only when populated — a guardrail created without one has no
2182
2193
  `mapping` in responses, and evaluates the whole record (or the
2183
2194
  record's own top-level `text` field, when it has one).
@@ -2353,7 +2364,8 @@ components:
2353
2364
  record field to the `text` input (e.g.
2354
2365
  `{"fields": [{"extract": "employeeSummary", "generate": "text"}]}`);
2355
2366
  only that field is evaluated, and fields outside it are neither
2356
- scanned nor masked. Optional — when omitted the whole record is
2367
+ scanned nor masked. A mapping can also generate `record`, an object
2368
+ evaluated as its JSON. Optional — when omitted the whole record is
2357
2369
  evaluated, serialized as JSON, unless the record has its own
2358
2370
  top-level `text` field, which is then evaluated alone. The server
2359
2371
  serves this field only when populated.
@@ -2362,10 +2374,13 @@ components:
2362
2374
  Send the input selection here as `mapping`, not as Mapper 2.0
2363
2375
  `mappings` rows. Map the field explicitly when records carry their
2364
2376
  own `text` field.
2377
+ - |-
2378
+ A guardrail keeps no conversation history, so a mapped
2379
+ `conversationHistoryId` changes nothing.
2365
2380
  properties:
2366
2381
  fields:
2367
2382
  type: array
2368
- description: Field-level mapping entries; `generate` targets the guardrail input (typically `text`).
2383
+ description: Field-level mapping entries; `generate` targets the guardrail input (`text`, or `record` for an object).
2369
2384
  items:
2370
2385
  $ref: '#/components/schemas/MappingField'
2371
2386
  lists:
@@ -1300,15 +1300,30 @@ components:
1300
1300
  - `"lessthan"`: Value is less than specified value (is less than)
1301
1301
  - `"lessthanequals"`: Value is less than or equal to specified value (is less than or equals)
1302
1302
  - `"startswith"`: String starts with specified prefix (starts with)
1303
+ - `"notstartswith"`: String does not start with specified prefix (does not start with)
1303
1304
  - `"endswith"`: String ends with specified suffix (ends with)
1305
+ - `"notendswith"`: String does not end with specified suffix (does not end with)
1304
1306
  - `"contains"`: String contains specified substring (contains)
1305
1307
  - `"doesnotcontain"`: String does not contain specified substring (does not contain)
1306
1308
  - `"empty"`: Field is missing or empty (is empty)
1307
1309
  - `"notempty"`: Field contains a value (is not empty)
1308
- - `"matches"`: Matches a regular expression (matches)
1310
+ - `"matches"`: Matches a regular expression, ignoring case (matches)
1309
1311
 
1310
- `isempty`, `isnotempty` and `anyof` are not operators: they are refused with 422
1311
- "Invalid operation: <name>".
1312
+ Operator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored
1313
+ as sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,
1314
+ `doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:
1315
+ they are refused with 422 "Invalid operation: <name>", with the name in lowercase,
1316
+ both when the filter is saved and by `POST /v1/processors/filter`. To negate a
1317
+ condition, wrap it in `not`.
1318
+
1319
+ The string comparisons (`equals`, `contains`, `startswith`, `endswith` and their
1320
+ negations) are case-sensitive; wrap the field in `lowercase` to compare without case.
1321
+ `matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also
1322
+ matches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`
1323
+ makes the pattern invalid. The filter still saves, but in a run every record fails
1324
+ with `FILTER_EVALUATION_FAILED` ("Invalid regular expression: /(?i)…/gi: Invalid
1325
+ group"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified
1326
+ 2026-10-22).
1312
1327
 
1313
1328
  **Logical Operators**
1314
1329
  - `"and"`: All conditions must be true
@@ -746,15 +746,30 @@ components:
746
746
  - `"lessthan"`: Value is less than specified value (is less than)
747
747
  - `"lessthanequals"`: Value is less than or equal to specified value (is less than or equals)
748
748
  - `"startswith"`: String starts with specified prefix (starts with)
749
+ - `"notstartswith"`: String does not start with specified prefix (does not start with)
749
750
  - `"endswith"`: String ends with specified suffix (ends with)
751
+ - `"notendswith"`: String does not end with specified suffix (does not end with)
750
752
  - `"contains"`: String contains specified substring (contains)
751
753
  - `"doesnotcontain"`: String does not contain specified substring (does not contain)
752
754
  - `"empty"`: Field is missing or empty (is empty)
753
755
  - `"notempty"`: Field contains a value (is not empty)
754
- - `"matches"`: Matches a regular expression (matches)
755
-
756
- `isempty`, `isnotempty` and `anyof` are not operators: they are refused with 422
757
- "Invalid operation: <name>".
756
+ - `"matches"`: Matches a regular expression, ignoring case (matches)
757
+
758
+ Operator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored
759
+ as sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,
760
+ `doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:
761
+ they are refused with 422 "Invalid operation: <name>", with the name in lowercase,
762
+ both when the filter is saved and by `POST /v1/processors/filter`. To negate a
763
+ condition, wrap it in `not`.
764
+
765
+ The string comparisons (`equals`, `contains`, `startswith`, `endswith` and their
766
+ negations) are case-sensitive; wrap the field in `lowercase` to compare without case.
767
+ `matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also
768
+ matches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`
769
+ makes the pattern invalid. The filter still saves, but in a run every record fails
770
+ with `FILTER_EVALUATION_FAILED` ("Invalid regular expression: /(?i)…/gi: Invalid
771
+ group"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified
772
+ 2026-10-22).
758
773
 
759
774
  **Logical Operators**
760
775
  - `"and"`: All conditions must be true