> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/api/api-reference/b2b-manager/trading-partner-connectors.md).

# Trading Partner Connectors

Trading partner connectors are reusable templates for onboarding EDI trading partners. Each connector defines pre-configured field values and fields the user must set for connections, exports, imports, and EDI profiles.

Connectors support expression-based conditions that control when certain field configurations apply. Publishing a connector makes it available to all accounts but requires the `allowedToPublishTPConnectors` permission.

### Trading partner connector schema

## The TradingPartnerConnector object

````json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"components":{"schemas":{"TradingPartnerConnector":{"type":"object","required":["_id","_userId","name","createdAt","lastModified"],"description":"Trading partner connector with metadata. The list endpoint returns a\nsummary shape (omits `published` and `supportedBy` but includes `type`,\n`region`, `model`, and `baseName` when set); GET by ID returns the full\nconfiguration.","allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns or created this trading partner connector."}}}]},"TradingPartnerConnectorBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","description":"Connector name. Must be unique across all published connectors."},"published":{"type":"boolean","default":false,"description":"Whether this connector is published and available platform-wide.\nRequires the `allowedToPublishTPConnectors` permission — without\nit, this field is silently ignored."},"helpURL":{"type":"string","anyOf":[{"format":"uri"},{"const":""}],"description":"URL to documentation for this trading partner connector. May be an\nempty string when no documentation link exists."},"type":{"type":"string","description":"Categorizes the connector by the transport its templates configure.\nAllowed values are configured per deployment — `FTP`, `AS2`, and `S3`\nby default. Absent from responses when never set (connectors created\nbefore this field existed omit it)."},"region":{"type":"string","description":"Geographic region the trading partner operates in, used to group\nconnectors in the catalog. Defaults to `North America` at creation\nwhen omitted; allowed values are configured per deployment (`North\nAmerica`, `European Union`, `Canada`, `USA`, and `Australia` by\ndefault). Connectors created before this field existed omit it."},"model":{"type":"string","description":"Business-model variant of the trading partner relationship, such as\n`Dropship`, `Warehouse`, or `DVS`. Defaults to `none` at creation when\nomitted, meaning the connector has no business-model variant; allowed\nvalues are configured per deployment. Connectors created before this\nfield existed omit it."},"baseName":{"type":"string","description":"Shared base name that groups related connector variants for the same\ntrading partner — for example, a partner's AS2 and FTP connectors.\nOnly present when set. Filter the list with the `baseName` query\nparameter to retrieve one group."},"supportedBy":{"type":"object","description":"Field configurations for each resource type involved in trading\npartner onboarding.","properties":{"ediProfile":{"$ref":"#/components/schemas/SupportedBySection"},"export":{"$ref":"#/components/schemas/SupportedBySection"},"import":{"$ref":"#/components/schemas/SupportedBySection"},"connection":{"$ref":"#/components/schemas/ConnectionSupportedBySection"}}}}},"SupportedBySection":{"type":"object","description":"Conditions, pre-configured field values, and fields the user must set\nfor a resource type (export, import, or EDI profile) during trading\npartner onboarding.","properties":{"conditions":{"type":"array","description":"Expression-based filters referenced by `_conditionIds` in\n`preConfiguredFields` and `fieldsUserMustSet`.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields set to predefined values during onboarding. In an EDI profile section, a value for\nyour own identity (`myInterchangeId`, `myGroupId`) or a placeholder partner ID such as\n`XXXXXXXXXXXXXXX` is a template stand-in, not a real value; the real IDs are among the\nfields the user must set.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide values for during onboarding.","items":{"$ref":"#/components/schemas/FieldUserMustSet"}}}},"Filter":{"type":"object","description":"Configuration for selectively processing records based on specified criteria. This object enables\nprecise control over which items are included or excluded from processing operations.\n\n**Filter behavior**\n\nWhen configured, the filter is applied before processing begins:\n- Items that match the filter criteria are processed\n- Items that don't match are completely skipped\n- No partial processing is performed\n\nSend the whole object. A rules array sent alone as the `filter` value is not\nstored, and a full update of an export that carries one removes the filter the\nexport had, with no error.\n\n**Implementation approaches**\n\nThere are two distinct filtering mechanisms available:\n\n**Rule-Based Filtering (`type: \"expression\"`)**\n- **Best For**: Common filtering patterns based on standard attributes\n- **Capabilities**: Filter by names, values, dates, numerical ranges, text patterns\n- **Advantages**: Declarative, no coding required, consistent performance\n- **Configuration**: Define rules in the `expression` object\n- **Use When**: You have clear, static criteria for selection\n\n**Script-Based Filtering (`type: \"script\"`)**\n- **Best For**: Complex logic, dynamic criteria, or business rules\n- **Capabilities**: Full programmatic control, access to complete metadata\n- **Advantages**: Maximum flexibility, can implement any filtering logic\n- **Configuration**: Reference a script in the `script` object\n- **Use When**: Simple rules aren't sufficient or logic needs to be dynamic\n","properties":{"type":{"type":"string","description":"Determines which filtering mechanism to use. This choice affects which properties\nmust be configured and how filtering logic is implemented.\n\n**Available types**\n\n**Rule-Based Filtering (`\"expression\"`)**\n- **Required Config**: The `expression` object with rule definitions\n- **Behavior**: Evaluates declarative rules against item attributes\n- **Best For**: Common patterns like name matching, date ranges, value limits\n- **Advantages**: Simpler to configure, no custom code required\n\n**Script-Based Filtering (`\"script\"`)**\n- **Required Config**: The `script` object with _scriptId and function\n- **Behavior**: Executes custom JavaScript to determine which items to process\n- **Best For**: Complex conditions, business logic, dynamic criteria\n- **Advantages**: Maximum flexibility, can implement any logic\n\n**Implementation guidance**\n\n1. For standard filtering needs (name, size, date), use `\"expression\"`\n2. For complex logic or conditions not covered by expressions, use `\"script\"`\n3. When selecting a type, you must configure the corresponding object:\n    - `type: \"expression\"` requires the `expression` object\n    - `type: \"script\"` requires the `script` object\n","enum":["expression","script"]},"expression":{"type":"object","description":"Configuration for declarative rule-based filtering. This object enables filtering\nitems based on common attributes without requiring custom code.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"expression\" and should not be\nconfigured otherwise. It provides a standardized way to define filtering rules that\ncan match against item attributes like name, type, value, date, and other properties.\n\n**Implementation guidance**\n\nThe expression system uses a rule-based approach where:\n- Rules can be combined with AND/OR logic\n- Each rule can check a specific attribute\n- Multiple conditions can be applied (ranges, pattern matching, exact matches)\n\n**Common filter patterns**\n\n1. **Pattern matching**: Regular expressions with `matches`\n2. **Value range filtering**: Numbers between min and max values\n3. **Date range filtering**: Items created/modified within specific time ranges\n4. **Status checking**: Items with specific status values or properties\n\nFor AI agents: Rule-based filtering should be your first choice when the filtering criteria\ncan be expressed in terms of standard attributes. Only use script-based filtering when\nmore complex logic is required.\n","properties":{"version":{"type":"string","description":"Version identifier for the expression format. Currently only version \"1\" is supported.\n\nThis field ensures future compatibility if the expression format evolves. Always set to \"1\"\nfor current implementations.\n","enum":["1"]},"rules":{"type":"array","description":"Expression array defining filter conditions using prefix notation. The first element is the operator,\nfollowed by its operands which may themselves be nested expression arrays.\n\nThe rule expression follows this pattern:\n- First element: Operator name (string)\n- Remaining elements: Operands for that operator (values or nested expressions)\n\n**Expression structure**\n\nFilter expressions use a prefix notation where operators appear before their operands:\n```\n[operator, operand1, operand2, ...]\n```\n\n**Comparison Operators**\n- `\"equals\"`: Exact match (equals)\n- `\"notequals\"`: Not equal to value (not equals)\n- `\"greaterthan\"`: Value is greater than specified value (is greater than)\n- `\"greaterthanequals\"`: Value is greater than or equal to specified value (is greater than or equals)\n- `\"lessthan\"`: Value is less than specified value (is less than)\n- `\"lessthanequals\"`: Value is less than or equal to specified value (is less than or equals)\n- `\"startswith\"`: String starts with specified prefix (starts with)\n- `\"notstartswith\"`: String does not start with specified prefix (does not start with)\n- `\"endswith\"`: String ends with specified suffix (ends with)\n- `\"notendswith\"`: String does not end with specified suffix (does not end with)\n- `\"contains\"`: String contains specified substring (contains)\n- `\"doesnotcontain\"`: String does not contain specified substring (does not contain)\n- `\"empty\"`: Field is missing or empty (is empty)\n- `\"notempty\"`: Field contains a value (is not empty)\n- `\"matches\"`: Matches a regular expression, ignoring case (matches)\n\nOperator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored\nas sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,\n`doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:\nthey are refused with 422 \"Invalid operation: <name>\", with the name in lowercase,\nboth when the filter is saved and by `POST /v1/processors/filter`. To negate a\ncondition, wrap it in `not`.\n\nThe string comparisons (`equals`, `contains`, `startswith`, `endswith` and their\nnegations) are case-sensitive; wrap the field in `lowercase` to compare without case.\n`matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also\nmatches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`\nmakes the pattern invalid. The filter still saves, but in a run every record fails\nwith `FILTER_EVALUATION_FAILED` (\"Invalid regular expression: /(?i)…/gi: Invalid\ngroup\"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified\n2026-10-22).\n\n**Logical Operators**\n- `\"and\"`: All conditions must be true\n- `\"or\"`: At least one condition must be true\n- `\"not\"`: Negates the condition\n\n**Field Access and Type Conversion**\n- `\"extract\"`: Access a field from the item by name\n- `\"settings\"`: Access a custom setting from the flow, flow step, or integration configuration\n- `\"boolean\"`: Convert value to Boolean type\n- `\"epochtime\"`: Convert value to Epoch Time (Unix timestamp)\n- `\"number\"`: Convert value to Number type\n- `\"string\"`: Convert value to String type\n\n**Field Access Details**\n\n**Using `extract` to access record fields:**\n- Retrieves values from the current record being processed\n- Can access nested properties using dot notation (e.g., `\"customer.email\"`)\n- Paths are relative to the record itself: `[\"extract\", \"record.status\"]`\n  matches nothing\n- In a record filter, must be wrapped in a type conversion (`string`, `number`,\n  `boolean` or `epochtime`): a bare `[\"extract\", ...]` operand is refused with 422\n  \"Field operation extract must be called by a Type Conversion Operation but was called\n  by <operator>\", both when an import's filter is saved and by\n  `POST /v1/processors/filter`\n\n**Using `settings` to access configuration values:**\n- Retrieves values from the integration's configuration settings\n- Supports different scopes with prefix notation:\n  - `flow.settingName`: Access flow-level settings\n  - `flowGrouping.settingName`: Access the flow group's settings\n  - `export.settingName`: Access the export's (or lookup's) own settings\n  - `import.settingName`: Access the import's own settings\n  - `integration.settingName`: Access integration-level settings\n  - `connection.settingName`, `iClient.settingName`: Access the step's\n    connection and iClient settings\n- A scope whose resource has no settings can be absent; a rule that reads\n  it matches nothing\n- Must be wrapped in a type conversion like `extract`: a bare\n  `[\"settings\", ...]` operand is refused with 422 \"Field operation settings\n  must be called by a Type Conversion Operation\"\n- Useful for dynamic filtering based on configuration\n\n**Field Transformations**\n- `\"lowercase\"`: Convert string to lowercase\n- `\"uppercase\"`: Convert string to uppercase\n- `\"ceiling\"`: Round number up to the nearest integer\n- `\"floor\"`: Round number down to the nearest integer\n- `\"abs\"`: Get absolute value of a number\n\n**Arithmetic** (number operands)\n- `\"add\"`, `\"subtract\"`, `\"multiply\"`, `\"divide\"`, `\"modulo\"`: for example\n  `[\"subtract\", [\"number\", [\"extract\", \"total\"]], [\"number\", [\"extract\", \"discount\"]]]`.\n  `mod` is not an operator (422 \"Invalid operation: mod.\").\n\n**Dates**\n- `epochtime` reads ISO 8601 strings and epoch-millisecond numbers. An empty\n  string, a string that isn't a date, or epoch milliseconds sent as a string\n  fail it with \"Invalid date. Cannot convert given string or number to date\n  time.\", followed by `; record=` and the record as JSON: in a run that record fails (`FILTER_EVALUATION_FAILED`, source\n  `output_filter` on an export), and `POST /v1/processors/filter` and an\n  export preview refuse the whole call with 422. `and` and `or` evaluate\n  every operand, so a `notempty` test beside it doesn't prevent the failure.\n  A missing or null field doesn't match.\n- `datetime`, `date` and `timestamp` are not type conversions: 422\n  \"Invalid operation: <name>.\"\n- `number` reads a missing or empty field as 0.\n\n**Handlebars operands**\n- An operand can also be a string holding exactly one Handlebars expression, such as\n  `\"{{record.status}}\"` or `\"{{lowercase record.code}}\"`, on either side of the\n  operator. It renders against the record (`record.<field>`; an unprefixed\n  `{{status}}` renders empty) before the comparison.\n- The rendered value is a string: wrap it in `[\"number\", ...]` to compare it with a\n  number, or the rule is refused with 422.\n- `epochtime` does not render Handlebars: `[\"epochtime\", \"{{timestamp}}\"]` is refused\n  with 422 \"invalid datetime format\".\n- A string with text around the expression, or with more than one expression, is\n  compared as a literal.\n- `[\"number\", \"{{timestamp \\\"x\\\"}}\"]` is the current time in epoch milliseconds,\n  so `[\"greaterthanequals\", [\"epochtime\", [\"extract\", \"created\"]], [\"subtract\",\n  [\"number\", \"{{timestamp \\\"x\\\"}}\"], 604800000]]` keeps records created in the\n  last 7 days.\n- An unknown helper fails the rule with 422 \"Failed to evaluate handlebars\n  expression\".\n\nChoose the type conversion that matches the comparison — `number` for numeric\ncomparisons, `epochtime` for dates, `string` for text. For example:\n\n```json\n[\n  \"equals\",\n  [\n    \"number\",  // Convert to number before comparison\n    [\n      \"extract\",\n      \"quantity\"\n    ]\n  ],\n  100\n]\n```\n\nExample with datetime conversion:\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",  // Convert to Unix timestamp before comparison\n    [\n      \"extract\",\n      \"createdDate\"\n    ]\n  ],\n  1609459200000  // January 1, 2021 as Unix timestamp in milliseconds\n]\n```\n\nExample with transformations:\n```json\n[\n  \"and\",\n  [\n    \"matches\",\n    [\n      \"lowercase\",  // Convert to lowercase before matching\n      [\n        \"string\",\n        [\n          \"extract\",\n          \"categories\"\n        ]\n      ]\n    ],\n    \"netsuite\"\n  ],\n  [\n    \"notequals\",\n    [\n      \"string\",\n      [\n        \"extract\",\n        \"recurrence.pattern.type\"\n      ]\n    ],\n    \"\"\n  ]\n]\n```\n\nExample comparing a record field with a flow setting:\n```json\n[\n  \"equals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"trantype\"\n    ]\n  ],\n  [\n    \"string\",\n    [\n      \"settings\",\n      \"flow.trantype\"\n    ]\n  ]\n]\n```\n\n**Examples**\n\nExample 1: Status field is not equal to \"cancelled\"\n```json\n[\n  \"notequals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"status\"\n    ]\n  ],\n  \"cancelled\"\n]\n```\n\nExample 2: Filename starts with \"HC\"\n```json\n[\n  \"startswith\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"filename\"\n    ]\n  ],\n  \"HC\"\n]\n```\n\nExample 3: Amount is greater than 100\n```json\n[\n  \"greaterthan\",\n  [\n    \"number\",\n    [\n      \"extract\",\n      \"amount\"\n    ]\n  ],\n  100\n]\n```\n\nExample 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`\nagainst epoch milliseconds: a `string` comparison of ISO timestamps orders values with\ndifferent UTC offsets wrongly.\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",\n    [\n      \"extract\",\n      \"orderDate\"\n    ]\n  ],\n  1672531200000\n]\n```\n","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"},{"title":"Array","type":"array"},{"title":"Null","type":"null"}]}}}},"script":{"type":"object","description":"Configuration for programmable script-based filtering. This object enables complex, custom\nfiltering logic beyond what expression-based filtering can provide.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"script\" and should not be configured\notherwise. It provides a way to execute custom JavaScript code to determine which items\nshould be processed.\n\n**Implementation approach**\n\nScript-based filtering works by:\n1. Executing the specified function from the referenced script\n2. Passing item data to the function\n3. Using the function's return value (true/false) to determine inclusion\n\n**Common use cases**\n\nScript filtering is ideal for:\n- Complex business logic that can't be expressed as simple rules\n- Dynamic filtering criteria that change based on external factors\n- Content-based filtering that requires deep inspection\n- Advanced pattern matching beyond simple wildcards\n- Multi-stage filtering with intermediate logic\n\nFor AI agents: Only use script-based filtering when expression-based filtering is insufficient.\nScript filtering requires maintaining custom code, which adds complexity to the integration.\n","properties":{"_scriptId":{"type":"string","description":"Reference to the Script resource that contains the filtering logic. This must be a valid\nObjectId of a Script resource in this account: any other id fails the save with 422\n(\"Only a script owned by the user or a script shared by the Integration App can be used\nat filter.script._scriptId.\").\n\nThe referenced script must contain the function specified in the `function` field\nand must be written to handle filtering specifically. The script receives\nitem data as its input and must return a boolean value indicating whether\nto process the item (true) or skip it (false).\n\nFormat: 24-character hexadecimal string (MongoDB ObjectId)\n"},"function":{"type":"string","description":"Name of the function within the script to execute for filtering decisions. This function\nmust exist in the script referenced by _scriptId.\n\n**Function requirements**\n\nThe specified function must:\n- Accept item data as its first parameter\n- Return a boolean value (true to process the item, false to skip it)\n- Handle errors gracefully\n- Execute efficiently (as it may run for many items)\n\n**Function signature**\n\n```javascript\nfunction filterItems(itemData) {\n  // itemData contains properties of the item being evaluated\n  // Custom logic here\n  return true; // or false to skip the item\n}\n```\n\nFor AI agents: Ensure the function name exactly matches a function defined in the\nreferenced script, as mismatches will cause the filter to fail.\n"}}}}},"PreConfiguredField":{"type":"object","description":"A field automatically set to a predefined value during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource."},"values":{"type":"array","description":"Value(s) to assign. Typically a single-element array.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply. If absent, always applies.","items":{"type":"string","format":"objectId"}}}},"FieldUserMustSet":{"type":"object","description":"A field the user must provide during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource, or the field's form label: EDI\nprofile sections commonly name fields by label (for example the trading partner\ninterchange ID), so map a label to its profile field before checking it."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI instead of the default."}}},"ConnectionSupportedBySection":{"type":"object","description":"Connection-specific section. Same as other `supportedBy` sections but\n`fieldsUserMustSet` entries may include `inputType` to control the UI\ninput widget.","properties":{"conditions":{"type":"array","description":"Expression-based filters for the connection section.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields automatically set on the connection during onboarding. Apart from the transport\n`type`, treat them as template stand-ins (published connectors carry values such as a\nplaceholder AS2 partner ID and a staging AS2 URI), not the partner's real settings; the\npartner's host and identity are in `fieldsUserMustSet`.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide for the connection.","items":{"$ref":"#/components/schemas/ConnectionFieldUserMustSet"}}}},"ConnectionFieldUserMustSet":{"type":"object","description":"Connection field the user must provide during onboarding. Adds\n`inputType` to control the UI input widget.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"inputType":{"type":"string","enum":["number","password","uri"],"description":"UI input widget type for this field."},"path":{"type":"string","description":"Dot-notation path of the field on the connection."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}}}}
````

## List trading partner connectors

> Returns all trading partner connectors visible to the caller. Published\
> connectors are visible to everyone; unpublished connectors are visible\
> only to their owner.\
> \
> The list response is a summary shape — it includes \`\_id\`, \`name\`,\
> \`\_userId\`, \`helpURL\`, timestamps, and the categorization fields (\`type\`,\
> \`region\`, \`model\`, \`baseName\`) when set, but omits \`published\` and\
> \`supportedBy\`. Use GET by ID to retrieve the full configuration.

````json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"tags":[{"name":"Trading Partner Connectors","description":"Trading partner connectors are reusable templates for onboarding EDI\ntrading partners. Each connector defines pre-configured field values\nand fields the user must set for connections, exports, imports, and\nEDI profiles.\n\nConnectors support expression-based conditions that control when\ncertain field configurations apply. Publishing a connector makes it\navailable to all accounts but requires the\n`allowedToPublishTPConnectors` permission.\n\n## Trading partner connector schema\n\n{% openapi-schemas spec=\"tradingpartnerconnector\" schemas=\"TradingPartnerConnector\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"TradingPartnerConnector":{"type":"object","required":["_id","_userId","name","createdAt","lastModified"],"description":"Trading partner connector with metadata. The list endpoint returns a\nsummary shape (omits `published` and `supportedBy` but includes `type`,\n`region`, `model`, and `baseName` when set); GET by ID returns the full\nconfiguration.","allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns or created this trading partner connector."}}}]},"TradingPartnerConnectorBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","description":"Connector name. Must be unique across all published connectors."},"published":{"type":"boolean","default":false,"description":"Whether this connector is published and available platform-wide.\nRequires the `allowedToPublishTPConnectors` permission — without\nit, this field is silently ignored."},"helpURL":{"type":"string","anyOf":[{"format":"uri"},{"const":""}],"description":"URL to documentation for this trading partner connector. May be an\nempty string when no documentation link exists."},"type":{"type":"string","description":"Categorizes the connector by the transport its templates configure.\nAllowed values are configured per deployment — `FTP`, `AS2`, and `S3`\nby default. Absent from responses when never set (connectors created\nbefore this field existed omit it)."},"region":{"type":"string","description":"Geographic region the trading partner operates in, used to group\nconnectors in the catalog. Defaults to `North America` at creation\nwhen omitted; allowed values are configured per deployment (`North\nAmerica`, `European Union`, `Canada`, `USA`, and `Australia` by\ndefault). Connectors created before this field existed omit it."},"model":{"type":"string","description":"Business-model variant of the trading partner relationship, such as\n`Dropship`, `Warehouse`, or `DVS`. Defaults to `none` at creation when\nomitted, meaning the connector has no business-model variant; allowed\nvalues are configured per deployment. Connectors created before this\nfield existed omit it."},"baseName":{"type":"string","description":"Shared base name that groups related connector variants for the same\ntrading partner — for example, a partner's AS2 and FTP connectors.\nOnly present when set. Filter the list with the `baseName` query\nparameter to retrieve one group."},"supportedBy":{"type":"object","description":"Field configurations for each resource type involved in trading\npartner onboarding.","properties":{"ediProfile":{"$ref":"#/components/schemas/SupportedBySection"},"export":{"$ref":"#/components/schemas/SupportedBySection"},"import":{"$ref":"#/components/schemas/SupportedBySection"},"connection":{"$ref":"#/components/schemas/ConnectionSupportedBySection"}}}}},"SupportedBySection":{"type":"object","description":"Conditions, pre-configured field values, and fields the user must set\nfor a resource type (export, import, or EDI profile) during trading\npartner onboarding.","properties":{"conditions":{"type":"array","description":"Expression-based filters referenced by `_conditionIds` in\n`preConfiguredFields` and `fieldsUserMustSet`.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields set to predefined values during onboarding. In an EDI profile section, a value for\nyour own identity (`myInterchangeId`, `myGroupId`) or a placeholder partner ID such as\n`XXXXXXXXXXXXXXX` is a template stand-in, not a real value; the real IDs are among the\nfields the user must set.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide values for during onboarding.","items":{"$ref":"#/components/schemas/FieldUserMustSet"}}}},"Filter":{"type":"object","description":"Configuration for selectively processing records based on specified criteria. This object enables\nprecise control over which items are included or excluded from processing operations.\n\n**Filter behavior**\n\nWhen configured, the filter is applied before processing begins:\n- Items that match the filter criteria are processed\n- Items that don't match are completely skipped\n- No partial processing is performed\n\nSend the whole object. A rules array sent alone as the `filter` value is not\nstored, and a full update of an export that carries one removes the filter the\nexport had, with no error.\n\n**Implementation approaches**\n\nThere are two distinct filtering mechanisms available:\n\n**Rule-Based Filtering (`type: \"expression\"`)**\n- **Best For**: Common filtering patterns based on standard attributes\n- **Capabilities**: Filter by names, values, dates, numerical ranges, text patterns\n- **Advantages**: Declarative, no coding required, consistent performance\n- **Configuration**: Define rules in the `expression` object\n- **Use When**: You have clear, static criteria for selection\n\n**Script-Based Filtering (`type: \"script\"`)**\n- **Best For**: Complex logic, dynamic criteria, or business rules\n- **Capabilities**: Full programmatic control, access to complete metadata\n- **Advantages**: Maximum flexibility, can implement any filtering logic\n- **Configuration**: Reference a script in the `script` object\n- **Use When**: Simple rules aren't sufficient or logic needs to be dynamic\n","properties":{"type":{"type":"string","description":"Determines which filtering mechanism to use. This choice affects which properties\nmust be configured and how filtering logic is implemented.\n\n**Available types**\n\n**Rule-Based Filtering (`\"expression\"`)**\n- **Required Config**: The `expression` object with rule definitions\n- **Behavior**: Evaluates declarative rules against item attributes\n- **Best For**: Common patterns like name matching, date ranges, value limits\n- **Advantages**: Simpler to configure, no custom code required\n\n**Script-Based Filtering (`\"script\"`)**\n- **Required Config**: The `script` object with _scriptId and function\n- **Behavior**: Executes custom JavaScript to determine which items to process\n- **Best For**: Complex conditions, business logic, dynamic criteria\n- **Advantages**: Maximum flexibility, can implement any logic\n\n**Implementation guidance**\n\n1. For standard filtering needs (name, size, date), use `\"expression\"`\n2. For complex logic or conditions not covered by expressions, use `\"script\"`\n3. When selecting a type, you must configure the corresponding object:\n    - `type: \"expression\"` requires the `expression` object\n    - `type: \"script\"` requires the `script` object\n","enum":["expression","script"]},"expression":{"type":"object","description":"Configuration for declarative rule-based filtering. This object enables filtering\nitems based on common attributes without requiring custom code.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"expression\" and should not be\nconfigured otherwise. It provides a standardized way to define filtering rules that\ncan match against item attributes like name, type, value, date, and other properties.\n\n**Implementation guidance**\n\nThe expression system uses a rule-based approach where:\n- Rules can be combined with AND/OR logic\n- Each rule can check a specific attribute\n- Multiple conditions can be applied (ranges, pattern matching, exact matches)\n\n**Common filter patterns**\n\n1. **Pattern matching**: Regular expressions with `matches`\n2. **Value range filtering**: Numbers between min and max values\n3. **Date range filtering**: Items created/modified within specific time ranges\n4. **Status checking**: Items with specific status values or properties\n\nFor AI agents: Rule-based filtering should be your first choice when the filtering criteria\ncan be expressed in terms of standard attributes. Only use script-based filtering when\nmore complex logic is required.\n","properties":{"version":{"type":"string","description":"Version identifier for the expression format. Currently only version \"1\" is supported.\n\nThis field ensures future compatibility if the expression format evolves. Always set to \"1\"\nfor current implementations.\n","enum":["1"]},"rules":{"type":"array","description":"Expression array defining filter conditions using prefix notation. The first element is the operator,\nfollowed by its operands which may themselves be nested expression arrays.\n\nThe rule expression follows this pattern:\n- First element: Operator name (string)\n- Remaining elements: Operands for that operator (values or nested expressions)\n\n**Expression structure**\n\nFilter expressions use a prefix notation where operators appear before their operands:\n```\n[operator, operand1, operand2, ...]\n```\n\n**Comparison Operators**\n- `\"equals\"`: Exact match (equals)\n- `\"notequals\"`: Not equal to value (not equals)\n- `\"greaterthan\"`: Value is greater than specified value (is greater than)\n- `\"greaterthanequals\"`: Value is greater than or equal to specified value (is greater than or equals)\n- `\"lessthan\"`: Value is less than specified value (is less than)\n- `\"lessthanequals\"`: Value is less than or equal to specified value (is less than or equals)\n- `\"startswith\"`: String starts with specified prefix (starts with)\n- `\"notstartswith\"`: String does not start with specified prefix (does not start with)\n- `\"endswith\"`: String ends with specified suffix (ends with)\n- `\"notendswith\"`: String does not end with specified suffix (does not end with)\n- `\"contains\"`: String contains specified substring (contains)\n- `\"doesnotcontain\"`: String does not contain specified substring (does not contain)\n- `\"empty\"`: Field is missing or empty (is empty)\n- `\"notempty\"`: Field contains a value (is not empty)\n- `\"matches\"`: Matches a regular expression, ignoring case (matches)\n\nOperator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored\nas sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,\n`doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:\nthey are refused with 422 \"Invalid operation: <name>\", with the name in lowercase,\nboth when the filter is saved and by `POST /v1/processors/filter`. To negate a\ncondition, wrap it in `not`.\n\nThe string comparisons (`equals`, `contains`, `startswith`, `endswith` and their\nnegations) are case-sensitive; wrap the field in `lowercase` to compare without case.\n`matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also\nmatches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`\nmakes the pattern invalid. The filter still saves, but in a run every record fails\nwith `FILTER_EVALUATION_FAILED` (\"Invalid regular expression: /(?i)…/gi: Invalid\ngroup\"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified\n2026-10-22).\n\n**Logical Operators**\n- `\"and\"`: All conditions must be true\n- `\"or\"`: At least one condition must be true\n- `\"not\"`: Negates the condition\n\n**Field Access and Type Conversion**\n- `\"extract\"`: Access a field from the item by name\n- `\"settings\"`: Access a custom setting from the flow, flow step, or integration configuration\n- `\"boolean\"`: Convert value to Boolean type\n- `\"epochtime\"`: Convert value to Epoch Time (Unix timestamp)\n- `\"number\"`: Convert value to Number type\n- `\"string\"`: Convert value to String type\n\n**Field Access Details**\n\n**Using `extract` to access record fields:**\n- Retrieves values from the current record being processed\n- Can access nested properties using dot notation (e.g., `\"customer.email\"`)\n- Paths are relative to the record itself: `[\"extract\", \"record.status\"]`\n  matches nothing\n- In a record filter, must be wrapped in a type conversion (`string`, `number`,\n  `boolean` or `epochtime`): a bare `[\"extract\", ...]` operand is refused with 422\n  \"Field operation extract must be called by a Type Conversion Operation but was called\n  by <operator>\", both when an import's filter is saved and by\n  `POST /v1/processors/filter`\n\n**Using `settings` to access configuration values:**\n- Retrieves values from the integration's configuration settings\n- Supports different scopes with prefix notation:\n  - `flow.settingName`: Access flow-level settings\n  - `flowGrouping.settingName`: Access the flow group's settings\n  - `export.settingName`: Access the export's (or lookup's) own settings\n  - `import.settingName`: Access the import's own settings\n  - `integration.settingName`: Access integration-level settings\n  - `connection.settingName`, `iClient.settingName`: Access the step's\n    connection and iClient settings\n- A scope whose resource has no settings can be absent; a rule that reads\n  it matches nothing\n- Must be wrapped in a type conversion like `extract`: a bare\n  `[\"settings\", ...]` operand is refused with 422 \"Field operation settings\n  must be called by a Type Conversion Operation\"\n- Useful for dynamic filtering based on configuration\n\n**Field Transformations**\n- `\"lowercase\"`: Convert string to lowercase\n- `\"uppercase\"`: Convert string to uppercase\n- `\"ceiling\"`: Round number up to the nearest integer\n- `\"floor\"`: Round number down to the nearest integer\n- `\"abs\"`: Get absolute value of a number\n\n**Arithmetic** (number operands)\n- `\"add\"`, `\"subtract\"`, `\"multiply\"`, `\"divide\"`, `\"modulo\"`: for example\n  `[\"subtract\", [\"number\", [\"extract\", \"total\"]], [\"number\", [\"extract\", \"discount\"]]]`.\n  `mod` is not an operator (422 \"Invalid operation: mod.\").\n\n**Dates**\n- `epochtime` reads ISO 8601 strings and epoch-millisecond numbers. An empty\n  string, a string that isn't a date, or epoch milliseconds sent as a string\n  fail it with \"Invalid date. Cannot convert given string or number to date\n  time.\", followed by `; record=` and the record as JSON: in a run that record fails (`FILTER_EVALUATION_FAILED`, source\n  `output_filter` on an export), and `POST /v1/processors/filter` and an\n  export preview refuse the whole call with 422. `and` and `or` evaluate\n  every operand, so a `notempty` test beside it doesn't prevent the failure.\n  A missing or null field doesn't match.\n- `datetime`, `date` and `timestamp` are not type conversions: 422\n  \"Invalid operation: <name>.\"\n- `number` reads a missing or empty field as 0.\n\n**Handlebars operands**\n- An operand can also be a string holding exactly one Handlebars expression, such as\n  `\"{{record.status}}\"` or `\"{{lowercase record.code}}\"`, on either side of the\n  operator. It renders against the record (`record.<field>`; an unprefixed\n  `{{status}}` renders empty) before the comparison.\n- The rendered value is a string: wrap it in `[\"number\", ...]` to compare it with a\n  number, or the rule is refused with 422.\n- `epochtime` does not render Handlebars: `[\"epochtime\", \"{{timestamp}}\"]` is refused\n  with 422 \"invalid datetime format\".\n- A string with text around the expression, or with more than one expression, is\n  compared as a literal.\n- `[\"number\", \"{{timestamp \\\"x\\\"}}\"]` is the current time in epoch milliseconds,\n  so `[\"greaterthanequals\", [\"epochtime\", [\"extract\", \"created\"]], [\"subtract\",\n  [\"number\", \"{{timestamp \\\"x\\\"}}\"], 604800000]]` keeps records created in the\n  last 7 days.\n- An unknown helper fails the rule with 422 \"Failed to evaluate handlebars\n  expression\".\n\nChoose the type conversion that matches the comparison — `number` for numeric\ncomparisons, `epochtime` for dates, `string` for text. For example:\n\n```json\n[\n  \"equals\",\n  [\n    \"number\",  // Convert to number before comparison\n    [\n      \"extract\",\n      \"quantity\"\n    ]\n  ],\n  100\n]\n```\n\nExample with datetime conversion:\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",  // Convert to Unix timestamp before comparison\n    [\n      \"extract\",\n      \"createdDate\"\n    ]\n  ],\n  1609459200000  // January 1, 2021 as Unix timestamp in milliseconds\n]\n```\n\nExample with transformations:\n```json\n[\n  \"and\",\n  [\n    \"matches\",\n    [\n      \"lowercase\",  // Convert to lowercase before matching\n      [\n        \"string\",\n        [\n          \"extract\",\n          \"categories\"\n        ]\n      ]\n    ],\n    \"netsuite\"\n  ],\n  [\n    \"notequals\",\n    [\n      \"string\",\n      [\n        \"extract\",\n        \"recurrence.pattern.type\"\n      ]\n    ],\n    \"\"\n  ]\n]\n```\n\nExample comparing a record field with a flow setting:\n```json\n[\n  \"equals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"trantype\"\n    ]\n  ],\n  [\n    \"string\",\n    [\n      \"settings\",\n      \"flow.trantype\"\n    ]\n  ]\n]\n```\n\n**Examples**\n\nExample 1: Status field is not equal to \"cancelled\"\n```json\n[\n  \"notequals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"status\"\n    ]\n  ],\n  \"cancelled\"\n]\n```\n\nExample 2: Filename starts with \"HC\"\n```json\n[\n  \"startswith\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"filename\"\n    ]\n  ],\n  \"HC\"\n]\n```\n\nExample 3: Amount is greater than 100\n```json\n[\n  \"greaterthan\",\n  [\n    \"number\",\n    [\n      \"extract\",\n      \"amount\"\n    ]\n  ],\n  100\n]\n```\n\nExample 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`\nagainst epoch milliseconds: a `string` comparison of ISO timestamps orders values with\ndifferent UTC offsets wrongly.\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",\n    [\n      \"extract\",\n      \"orderDate\"\n    ]\n  ],\n  1672531200000\n]\n```\n","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"},{"title":"Array","type":"array"},{"title":"Null","type":"null"}]}}}},"script":{"type":"object","description":"Configuration for programmable script-based filtering. This object enables complex, custom\nfiltering logic beyond what expression-based filtering can provide.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"script\" and should not be configured\notherwise. It provides a way to execute custom JavaScript code to determine which items\nshould be processed.\n\n**Implementation approach**\n\nScript-based filtering works by:\n1. Executing the specified function from the referenced script\n2. Passing item data to the function\n3. Using the function's return value (true/false) to determine inclusion\n\n**Common use cases**\n\nScript filtering is ideal for:\n- Complex business logic that can't be expressed as simple rules\n- Dynamic filtering criteria that change based on external factors\n- Content-based filtering that requires deep inspection\n- Advanced pattern matching beyond simple wildcards\n- Multi-stage filtering with intermediate logic\n\nFor AI agents: Only use script-based filtering when expression-based filtering is insufficient.\nScript filtering requires maintaining custom code, which adds complexity to the integration.\n","properties":{"_scriptId":{"type":"string","description":"Reference to the Script resource that contains the filtering logic. This must be a valid\nObjectId of a Script resource in this account: any other id fails the save with 422\n(\"Only a script owned by the user or a script shared by the Integration App can be used\nat filter.script._scriptId.\").\n\nThe referenced script must contain the function specified in the `function` field\nand must be written to handle filtering specifically. The script receives\nitem data as its input and must return a boolean value indicating whether\nto process the item (true) or skip it (false).\n\nFormat: 24-character hexadecimal string (MongoDB ObjectId)\n"},"function":{"type":"string","description":"Name of the function within the script to execute for filtering decisions. This function\nmust exist in the script referenced by _scriptId.\n\n**Function requirements**\n\nThe specified function must:\n- Accept item data as its first parameter\n- Return a boolean value (true to process the item, false to skip it)\n- Handle errors gracefully\n- Execute efficiently (as it may run for many items)\n\n**Function signature**\n\n```javascript\nfunction filterItems(itemData) {\n  // itemData contains properties of the item being evaluated\n  // Custom logic here\n  return true; // or false to skip the item\n}\n```\n\nFor AI agents: Ensure the function name exactly matches a function defined in the\nreferenced script, as mismatches will cause the filter to fail.\n"}}}}},"PreConfiguredField":{"type":"object","description":"A field automatically set to a predefined value during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource."},"values":{"type":"array","description":"Value(s) to assign. Typically a single-element array.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply. If absent, always applies.","items":{"type":"string","format":"objectId"}}}},"FieldUserMustSet":{"type":"object","description":"A field the user must provide during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource, or the field's form label: EDI\nprofile sections commonly name fields by label (for example the trading partner\ninterchange ID), so map a label to its profile field before checking it."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI instead of the default."}}},"ConnectionSupportedBySection":{"type":"object","description":"Connection-specific section. Same as other `supportedBy` sections but\n`fieldsUserMustSet` entries may include `inputType` to control the UI\ninput widget.","properties":{"conditions":{"type":"array","description":"Expression-based filters for the connection section.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields automatically set on the connection during onboarding. Apart from the transport\n`type`, treat them as template stand-ins (published connectors carry values such as a\nplaceholder AS2 partner ID and a staging AS2 URI), not the partner's real settings; the\npartner's host and identity are in `fieldsUserMustSet`.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide for the connection.","items":{"$ref":"#/components/schemas/ConnectionFieldUserMustSet"}}}},"ConnectionFieldUserMustSet":{"type":"object","description":"Connection field the user must provide during onboarding. Adds\n`inputType` to control the UI input widget.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"inputType":{"type":"string","enum":["number","password","uri"],"description":"UI input widget type for this field."},"path":{"type":"string","description":"Dot-notation path of the field on the connection."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/tpconnectors":{"get":{"summary":"List trading partner connectors","description":"Returns all trading partner connectors visible to the caller. Published\nconnectors are visible to everyone; unpublished connectors are visible\nonly to their owner.\n\nThe list response is a summary shape — it includes `_id`, `name`,\n`_userId`, `helpURL`, timestamps, and the categorization fields (`type`,\n`region`, `model`, `baseName`) when set, but omits `published` and\n`supportedBy`. Use GET by ID to retrieve the full configuration.","operationId":"listTradingPartnerConnectors","tags":["Trading Partner Connectors"],"parameters":[{"name":"publishedOnly","in":"query","description":"When set to `true`, only published connectors are returned.","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"baseName","in":"query","required":false,"description":"Filter to connectors whose `baseName` exactly matches this value —\ntypically one trading partner's group of connector variants. Must be\nsupplied once; repeating the parameter returns `422\ninvalid_query_param`. Returns `204` when nothing matches.","schema":{"type":"string"}},{"name":"distinct","in":"query","required":false,"description":"Changes the response shape: instead of connector objects, returns a\nsorted array of the distinct `baseName` values across **published**\nconnectors (unpublished connectors are excluded even for their\nowner). Combine with other filters to scope the set. Returns `204`\nwhen no published connector has a `baseName`. Any value other than\n`baseName` fails with `422 invalid_query_param`\n(\"distinct must be 'baseName'.\").","schema":{"type":"string","enum":["baseName"]}}],"responses":{"200":{"description":"Successfully retrieved list of trading partner connectors. With\n`?distinct=baseName` the body is instead a sorted array of strings\n(the distinct `baseName` values), e.g. `[\"Acme Corp\", \"Bravo Inc\"]`.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TradingPartnerConnector"}}}}},"204":{"description":"No trading partner connectors exist, or none matches the supplied filter."},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"description":"The `baseName` query parameter was supplied more than once (or is\notherwise not a single string), or `distinct` was set to a value\nother than `baseName`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
````

## Create a trading partner connector

> Creates a new trading partner connector. Only \`name\` is required.\
> Setting \`published: true\` requires the\
> \`allowedToPublishTPConnectors\` permission; without it the field is\
> silently ignored.

````json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"tags":[{"name":"Trading Partner Connectors","description":"Trading partner connectors are reusable templates for onboarding EDI\ntrading partners. Each connector defines pre-configured field values\nand fields the user must set for connections, exports, imports, and\nEDI profiles.\n\nConnectors support expression-based conditions that control when\ncertain field configurations apply. Publishing a connector makes it\navailable to all accounts but requires the\n`allowedToPublishTPConnectors` permission.\n\n## Trading partner connector schema\n\n{% openapi-schemas spec=\"tradingpartnerconnector\" schemas=\"TradingPartnerConnector\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Request schema for creating or updating a trading partner connector.\nOnly `name` is required for creation. Connection\n`preConfiguredFields` must include a `type` path (e.g. `ftp` or\n`as2`) and export/import must include `file.type` set to\n`filedefinition` -- these are validated when `published` is `true`.\n\n`type`, `region`, and `model` must match the deployment's configured\nvalues exactly, including case. A value outside the list is not\nrejected with a validation error: the request never completes (no\nresponse is returned) and nothing is created or changed.","required":["name"],"allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"}]},"TradingPartnerConnectorBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","description":"Connector name. Must be unique across all published connectors."},"published":{"type":"boolean","default":false,"description":"Whether this connector is published and available platform-wide.\nRequires the `allowedToPublishTPConnectors` permission — without\nit, this field is silently ignored."},"helpURL":{"type":"string","anyOf":[{"format":"uri"},{"const":""}],"description":"URL to documentation for this trading partner connector. May be an\nempty string when no documentation link exists."},"type":{"type":"string","description":"Categorizes the connector by the transport its templates configure.\nAllowed values are configured per deployment — `FTP`, `AS2`, and `S3`\nby default. Absent from responses when never set (connectors created\nbefore this field existed omit it)."},"region":{"type":"string","description":"Geographic region the trading partner operates in, used to group\nconnectors in the catalog. Defaults to `North America` at creation\nwhen omitted; allowed values are configured per deployment (`North\nAmerica`, `European Union`, `Canada`, `USA`, and `Australia` by\ndefault). Connectors created before this field existed omit it."},"model":{"type":"string","description":"Business-model variant of the trading partner relationship, such as\n`Dropship`, `Warehouse`, or `DVS`. Defaults to `none` at creation when\nomitted, meaning the connector has no business-model variant; allowed\nvalues are configured per deployment. Connectors created before this\nfield existed omit it."},"baseName":{"type":"string","description":"Shared base name that groups related connector variants for the same\ntrading partner — for example, a partner's AS2 and FTP connectors.\nOnly present when set. Filter the list with the `baseName` query\nparameter to retrieve one group."},"supportedBy":{"type":"object","description":"Field configurations for each resource type involved in trading\npartner onboarding.","properties":{"ediProfile":{"$ref":"#/components/schemas/SupportedBySection"},"export":{"$ref":"#/components/schemas/SupportedBySection"},"import":{"$ref":"#/components/schemas/SupportedBySection"},"connection":{"$ref":"#/components/schemas/ConnectionSupportedBySection"}}}}},"SupportedBySection":{"type":"object","description":"Conditions, pre-configured field values, and fields the user must set\nfor a resource type (export, import, or EDI profile) during trading\npartner onboarding.","properties":{"conditions":{"type":"array","description":"Expression-based filters referenced by `_conditionIds` in\n`preConfiguredFields` and `fieldsUserMustSet`.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields set to predefined values during onboarding. In an EDI profile section, a value for\nyour own identity (`myInterchangeId`, `myGroupId`) or a placeholder partner ID such as\n`XXXXXXXXXXXXXXX` is a template stand-in, not a real value; the real IDs are among the\nfields the user must set.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide values for during onboarding.","items":{"$ref":"#/components/schemas/FieldUserMustSet"}}}},"Filter":{"type":"object","description":"Configuration for selectively processing records based on specified criteria. This object enables\nprecise control over which items are included or excluded from processing operations.\n\n**Filter behavior**\n\nWhen configured, the filter is applied before processing begins:\n- Items that match the filter criteria are processed\n- Items that don't match are completely skipped\n- No partial processing is performed\n\nSend the whole object. A rules array sent alone as the `filter` value is not\nstored, and a full update of an export that carries one removes the filter the\nexport had, with no error.\n\n**Implementation approaches**\n\nThere are two distinct filtering mechanisms available:\n\n**Rule-Based Filtering (`type: \"expression\"`)**\n- **Best For**: Common filtering patterns based on standard attributes\n- **Capabilities**: Filter by names, values, dates, numerical ranges, text patterns\n- **Advantages**: Declarative, no coding required, consistent performance\n- **Configuration**: Define rules in the `expression` object\n- **Use When**: You have clear, static criteria for selection\n\n**Script-Based Filtering (`type: \"script\"`)**\n- **Best For**: Complex logic, dynamic criteria, or business rules\n- **Capabilities**: Full programmatic control, access to complete metadata\n- **Advantages**: Maximum flexibility, can implement any filtering logic\n- **Configuration**: Reference a script in the `script` object\n- **Use When**: Simple rules aren't sufficient or logic needs to be dynamic\n","properties":{"type":{"type":"string","description":"Determines which filtering mechanism to use. This choice affects which properties\nmust be configured and how filtering logic is implemented.\n\n**Available types**\n\n**Rule-Based Filtering (`\"expression\"`)**\n- **Required Config**: The `expression` object with rule definitions\n- **Behavior**: Evaluates declarative rules against item attributes\n- **Best For**: Common patterns like name matching, date ranges, value limits\n- **Advantages**: Simpler to configure, no custom code required\n\n**Script-Based Filtering (`\"script\"`)**\n- **Required Config**: The `script` object with _scriptId and function\n- **Behavior**: Executes custom JavaScript to determine which items to process\n- **Best For**: Complex conditions, business logic, dynamic criteria\n- **Advantages**: Maximum flexibility, can implement any logic\n\n**Implementation guidance**\n\n1. For standard filtering needs (name, size, date), use `\"expression\"`\n2. For complex logic or conditions not covered by expressions, use `\"script\"`\n3. When selecting a type, you must configure the corresponding object:\n    - `type: \"expression\"` requires the `expression` object\n    - `type: \"script\"` requires the `script` object\n","enum":["expression","script"]},"expression":{"type":"object","description":"Configuration for declarative rule-based filtering. This object enables filtering\nitems based on common attributes without requiring custom code.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"expression\" and should not be\nconfigured otherwise. It provides a standardized way to define filtering rules that\ncan match against item attributes like name, type, value, date, and other properties.\n\n**Implementation guidance**\n\nThe expression system uses a rule-based approach where:\n- Rules can be combined with AND/OR logic\n- Each rule can check a specific attribute\n- Multiple conditions can be applied (ranges, pattern matching, exact matches)\n\n**Common filter patterns**\n\n1. **Pattern matching**: Regular expressions with `matches`\n2. **Value range filtering**: Numbers between min and max values\n3. **Date range filtering**: Items created/modified within specific time ranges\n4. **Status checking**: Items with specific status values or properties\n\nFor AI agents: Rule-based filtering should be your first choice when the filtering criteria\ncan be expressed in terms of standard attributes. Only use script-based filtering when\nmore complex logic is required.\n","properties":{"version":{"type":"string","description":"Version identifier for the expression format. Currently only version \"1\" is supported.\n\nThis field ensures future compatibility if the expression format evolves. Always set to \"1\"\nfor current implementations.\n","enum":["1"]},"rules":{"type":"array","description":"Expression array defining filter conditions using prefix notation. The first element is the operator,\nfollowed by its operands which may themselves be nested expression arrays.\n\nThe rule expression follows this pattern:\n- First element: Operator name (string)\n- Remaining elements: Operands for that operator (values or nested expressions)\n\n**Expression structure**\n\nFilter expressions use a prefix notation where operators appear before their operands:\n```\n[operator, operand1, operand2, ...]\n```\n\n**Comparison Operators**\n- `\"equals\"`: Exact match (equals)\n- `\"notequals\"`: Not equal to value (not equals)\n- `\"greaterthan\"`: Value is greater than specified value (is greater than)\n- `\"greaterthanequals\"`: Value is greater than or equal to specified value (is greater than or equals)\n- `\"lessthan\"`: Value is less than specified value (is less than)\n- `\"lessthanequals\"`: Value is less than or equal to specified value (is less than or equals)\n- `\"startswith\"`: String starts with specified prefix (starts with)\n- `\"notstartswith\"`: String does not start with specified prefix (does not start with)\n- `\"endswith\"`: String ends with specified suffix (ends with)\n- `\"notendswith\"`: String does not end with specified suffix (does not end with)\n- `\"contains\"`: String contains specified substring (contains)\n- `\"doesnotcontain\"`: String does not contain specified substring (does not contain)\n- `\"empty\"`: Field is missing or empty (is empty)\n- `\"notempty\"`: Field contains a value (is not empty)\n- `\"matches\"`: Matches a regular expression, ignoring case (matches)\n\nOperator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored\nas sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,\n`doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:\nthey are refused with 422 \"Invalid operation: <name>\", with the name in lowercase,\nboth when the filter is saved and by `POST /v1/processors/filter`. To negate a\ncondition, wrap it in `not`.\n\nThe string comparisons (`equals`, `contains`, `startswith`, `endswith` and their\nnegations) are case-sensitive; wrap the field in `lowercase` to compare without case.\n`matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also\nmatches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`\nmakes the pattern invalid. The filter still saves, but in a run every record fails\nwith `FILTER_EVALUATION_FAILED` (\"Invalid regular expression: /(?i)…/gi: Invalid\ngroup\"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified\n2026-10-22).\n\n**Logical Operators**\n- `\"and\"`: All conditions must be true\n- `\"or\"`: At least one condition must be true\n- `\"not\"`: Negates the condition\n\n**Field Access and Type Conversion**\n- `\"extract\"`: Access a field from the item by name\n- `\"settings\"`: Access a custom setting from the flow, flow step, or integration configuration\n- `\"boolean\"`: Convert value to Boolean type\n- `\"epochtime\"`: Convert value to Epoch Time (Unix timestamp)\n- `\"number\"`: Convert value to Number type\n- `\"string\"`: Convert value to String type\n\n**Field Access Details**\n\n**Using `extract` to access record fields:**\n- Retrieves values from the current record being processed\n- Can access nested properties using dot notation (e.g., `\"customer.email\"`)\n- Paths are relative to the record itself: `[\"extract\", \"record.status\"]`\n  matches nothing\n- In a record filter, must be wrapped in a type conversion (`string`, `number`,\n  `boolean` or `epochtime`): a bare `[\"extract\", ...]` operand is refused with 422\n  \"Field operation extract must be called by a Type Conversion Operation but was called\n  by <operator>\", both when an import's filter is saved and by\n  `POST /v1/processors/filter`\n\n**Using `settings` to access configuration values:**\n- Retrieves values from the integration's configuration settings\n- Supports different scopes with prefix notation:\n  - `flow.settingName`: Access flow-level settings\n  - `flowGrouping.settingName`: Access the flow group's settings\n  - `export.settingName`: Access the export's (or lookup's) own settings\n  - `import.settingName`: Access the import's own settings\n  - `integration.settingName`: Access integration-level settings\n  - `connection.settingName`, `iClient.settingName`: Access the step's\n    connection and iClient settings\n- A scope whose resource has no settings can be absent; a rule that reads\n  it matches nothing\n- Must be wrapped in a type conversion like `extract`: a bare\n  `[\"settings\", ...]` operand is refused with 422 \"Field operation settings\n  must be called by a Type Conversion Operation\"\n- Useful for dynamic filtering based on configuration\n\n**Field Transformations**\n- `\"lowercase\"`: Convert string to lowercase\n- `\"uppercase\"`: Convert string to uppercase\n- `\"ceiling\"`: Round number up to the nearest integer\n- `\"floor\"`: Round number down to the nearest integer\n- `\"abs\"`: Get absolute value of a number\n\n**Arithmetic** (number operands)\n- `\"add\"`, `\"subtract\"`, `\"multiply\"`, `\"divide\"`, `\"modulo\"`: for example\n  `[\"subtract\", [\"number\", [\"extract\", \"total\"]], [\"number\", [\"extract\", \"discount\"]]]`.\n  `mod` is not an operator (422 \"Invalid operation: mod.\").\n\n**Dates**\n- `epochtime` reads ISO 8601 strings and epoch-millisecond numbers. An empty\n  string, a string that isn't a date, or epoch milliseconds sent as a string\n  fail it with \"Invalid date. Cannot convert given string or number to date\n  time.\", followed by `; record=` and the record as JSON: in a run that record fails (`FILTER_EVALUATION_FAILED`, source\n  `output_filter` on an export), and `POST /v1/processors/filter` and an\n  export preview refuse the whole call with 422. `and` and `or` evaluate\n  every operand, so a `notempty` test beside it doesn't prevent the failure.\n  A missing or null field doesn't match.\n- `datetime`, `date` and `timestamp` are not type conversions: 422\n  \"Invalid operation: <name>.\"\n- `number` reads a missing or empty field as 0.\n\n**Handlebars operands**\n- An operand can also be a string holding exactly one Handlebars expression, such as\n  `\"{{record.status}}\"` or `\"{{lowercase record.code}}\"`, on either side of the\n  operator. It renders against the record (`record.<field>`; an unprefixed\n  `{{status}}` renders empty) before the comparison.\n- The rendered value is a string: wrap it in `[\"number\", ...]` to compare it with a\n  number, or the rule is refused with 422.\n- `epochtime` does not render Handlebars: `[\"epochtime\", \"{{timestamp}}\"]` is refused\n  with 422 \"invalid datetime format\".\n- A string with text around the expression, or with more than one expression, is\n  compared as a literal.\n- `[\"number\", \"{{timestamp \\\"x\\\"}}\"]` is the current time in epoch milliseconds,\n  so `[\"greaterthanequals\", [\"epochtime\", [\"extract\", \"created\"]], [\"subtract\",\n  [\"number\", \"{{timestamp \\\"x\\\"}}\"], 604800000]]` keeps records created in the\n  last 7 days.\n- An unknown helper fails the rule with 422 \"Failed to evaluate handlebars\n  expression\".\n\nChoose the type conversion that matches the comparison — `number` for numeric\ncomparisons, `epochtime` for dates, `string` for text. For example:\n\n```json\n[\n  \"equals\",\n  [\n    \"number\",  // Convert to number before comparison\n    [\n      \"extract\",\n      \"quantity\"\n    ]\n  ],\n  100\n]\n```\n\nExample with datetime conversion:\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",  // Convert to Unix timestamp before comparison\n    [\n      \"extract\",\n      \"createdDate\"\n    ]\n  ],\n  1609459200000  // January 1, 2021 as Unix timestamp in milliseconds\n]\n```\n\nExample with transformations:\n```json\n[\n  \"and\",\n  [\n    \"matches\",\n    [\n      \"lowercase\",  // Convert to lowercase before matching\n      [\n        \"string\",\n        [\n          \"extract\",\n          \"categories\"\n        ]\n      ]\n    ],\n    \"netsuite\"\n  ],\n  [\n    \"notequals\",\n    [\n      \"string\",\n      [\n        \"extract\",\n        \"recurrence.pattern.type\"\n      ]\n    ],\n    \"\"\n  ]\n]\n```\n\nExample comparing a record field with a flow setting:\n```json\n[\n  \"equals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"trantype\"\n    ]\n  ],\n  [\n    \"string\",\n    [\n      \"settings\",\n      \"flow.trantype\"\n    ]\n  ]\n]\n```\n\n**Examples**\n\nExample 1: Status field is not equal to \"cancelled\"\n```json\n[\n  \"notequals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"status\"\n    ]\n  ],\n  \"cancelled\"\n]\n```\n\nExample 2: Filename starts with \"HC\"\n```json\n[\n  \"startswith\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"filename\"\n    ]\n  ],\n  \"HC\"\n]\n```\n\nExample 3: Amount is greater than 100\n```json\n[\n  \"greaterthan\",\n  [\n    \"number\",\n    [\n      \"extract\",\n      \"amount\"\n    ]\n  ],\n  100\n]\n```\n\nExample 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`\nagainst epoch milliseconds: a `string` comparison of ISO timestamps orders values with\ndifferent UTC offsets wrongly.\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",\n    [\n      \"extract\",\n      \"orderDate\"\n    ]\n  ],\n  1672531200000\n]\n```\n","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"},{"title":"Array","type":"array"},{"title":"Null","type":"null"}]}}}},"script":{"type":"object","description":"Configuration for programmable script-based filtering. This object enables complex, custom\nfiltering logic beyond what expression-based filtering can provide.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"script\" and should not be configured\notherwise. It provides a way to execute custom JavaScript code to determine which items\nshould be processed.\n\n**Implementation approach**\n\nScript-based filtering works by:\n1. Executing the specified function from the referenced script\n2. Passing item data to the function\n3. Using the function's return value (true/false) to determine inclusion\n\n**Common use cases**\n\nScript filtering is ideal for:\n- Complex business logic that can't be expressed as simple rules\n- Dynamic filtering criteria that change based on external factors\n- Content-based filtering that requires deep inspection\n- Advanced pattern matching beyond simple wildcards\n- Multi-stage filtering with intermediate logic\n\nFor AI agents: Only use script-based filtering when expression-based filtering is insufficient.\nScript filtering requires maintaining custom code, which adds complexity to the integration.\n","properties":{"_scriptId":{"type":"string","description":"Reference to the Script resource that contains the filtering logic. This must be a valid\nObjectId of a Script resource in this account: any other id fails the save with 422\n(\"Only a script owned by the user or a script shared by the Integration App can be used\nat filter.script._scriptId.\").\n\nThe referenced script must contain the function specified in the `function` field\nand must be written to handle filtering specifically. The script receives\nitem data as its input and must return a boolean value indicating whether\nto process the item (true) or skip it (false).\n\nFormat: 24-character hexadecimal string (MongoDB ObjectId)\n"},"function":{"type":"string","description":"Name of the function within the script to execute for filtering decisions. This function\nmust exist in the script referenced by _scriptId.\n\n**Function requirements**\n\nThe specified function must:\n- Accept item data as its first parameter\n- Return a boolean value (true to process the item, false to skip it)\n- Handle errors gracefully\n- Execute efficiently (as it may run for many items)\n\n**Function signature**\n\n```javascript\nfunction filterItems(itemData) {\n  // itemData contains properties of the item being evaluated\n  // Custom logic here\n  return true; // or false to skip the item\n}\n```\n\nFor AI agents: Ensure the function name exactly matches a function defined in the\nreferenced script, as mismatches will cause the filter to fail.\n"}}}}},"PreConfiguredField":{"type":"object","description":"A field automatically set to a predefined value during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource."},"values":{"type":"array","description":"Value(s) to assign. Typically a single-element array.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply. If absent, always applies.","items":{"type":"string","format":"objectId"}}}},"FieldUserMustSet":{"type":"object","description":"A field the user must provide during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource, or the field's form label: EDI\nprofile sections commonly name fields by label (for example the trading partner\ninterchange ID), so map a label to its profile field before checking it."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI instead of the default."}}},"ConnectionSupportedBySection":{"type":"object","description":"Connection-specific section. Same as other `supportedBy` sections but\n`fieldsUserMustSet` entries may include `inputType` to control the UI\ninput widget.","properties":{"conditions":{"type":"array","description":"Expression-based filters for the connection section.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields automatically set on the connection during onboarding. Apart from the transport\n`type`, treat them as template stand-ins (published connectors carry values such as a\nplaceholder AS2 partner ID and a staging AS2 URI), not the partner's real settings; the\npartner's host and identity are in `fieldsUserMustSet`.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide for the connection.","items":{"$ref":"#/components/schemas/ConnectionFieldUserMustSet"}}}},"ConnectionFieldUserMustSet":{"type":"object","description":"Connection field the user must provide during onboarding. Adds\n`inputType` to control the UI input widget.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"inputType":{"type":"string","enum":["number","password","uri"],"description":"UI input widget type for this field."},"path":{"type":"string","description":"Dot-notation path of the field on the connection."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI."}}},"TradingPartnerConnector":{"type":"object","required":["_id","_userId","name","createdAt","lastModified"],"description":"Trading partner connector with metadata. The list endpoint returns a\nsummary shape (omits `published` and `supportedBy` but includes `type`,\n`region`, `model`, and `baseName` when set); GET by ID returns the full\nconfiguration.","allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns or created this trading partner connector."}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/tpconnectors":{"post":{"summary":"Create a trading partner connector","description":"Creates a new trading partner connector. Only `name` is required.\nSetting `published: true` requires the\n`allowedToPublishTPConnectors` permission; without it the field is\nsilently ignored.","operationId":"createTradingPartnerConnector","tags":["Trading Partner Connectors"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"201":{"description":"Trading partner connector created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingPartnerConnector"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
````

## Get a trading partner connector

> Returns the complete configuration of a trading partner connector,\
> including all \`supportedBy\` sections. Unpublished connectors are\
> only visible to their owner. The list endpoint returns a summary\
> that omits \`published\` and \`supportedBy\`.

````json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"tags":[{"name":"Trading Partner Connectors","description":"Trading partner connectors are reusable templates for onboarding EDI\ntrading partners. Each connector defines pre-configured field values\nand fields the user must set for connections, exports, imports, and\nEDI profiles.\n\nConnectors support expression-based conditions that control when\ncertain field configurations apply. Publishing a connector makes it\navailable to all accounts but requires the\n`allowedToPublishTPConnectors` permission.\n\n## Trading partner connector schema\n\n{% openapi-schemas spec=\"tradingpartnerconnector\" schemas=\"TradingPartnerConnector\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"TradingPartnerConnector":{"type":"object","required":["_id","_userId","name","createdAt","lastModified"],"description":"Trading partner connector with metadata. The list endpoint returns a\nsummary shape (omits `published` and `supportedBy` but includes `type`,\n`region`, `model`, and `baseName` when set); GET by ID returns the full\nconfiguration.","allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns or created this trading partner connector."}}}]},"TradingPartnerConnectorBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","description":"Connector name. Must be unique across all published connectors."},"published":{"type":"boolean","default":false,"description":"Whether this connector is published and available platform-wide.\nRequires the `allowedToPublishTPConnectors` permission — without\nit, this field is silently ignored."},"helpURL":{"type":"string","anyOf":[{"format":"uri"},{"const":""}],"description":"URL to documentation for this trading partner connector. May be an\nempty string when no documentation link exists."},"type":{"type":"string","description":"Categorizes the connector by the transport its templates configure.\nAllowed values are configured per deployment — `FTP`, `AS2`, and `S3`\nby default. Absent from responses when never set (connectors created\nbefore this field existed omit it)."},"region":{"type":"string","description":"Geographic region the trading partner operates in, used to group\nconnectors in the catalog. Defaults to `North America` at creation\nwhen omitted; allowed values are configured per deployment (`North\nAmerica`, `European Union`, `Canada`, `USA`, and `Australia` by\ndefault). Connectors created before this field existed omit it."},"model":{"type":"string","description":"Business-model variant of the trading partner relationship, such as\n`Dropship`, `Warehouse`, or `DVS`. Defaults to `none` at creation when\nomitted, meaning the connector has no business-model variant; allowed\nvalues are configured per deployment. Connectors created before this\nfield existed omit it."},"baseName":{"type":"string","description":"Shared base name that groups related connector variants for the same\ntrading partner — for example, a partner's AS2 and FTP connectors.\nOnly present when set. Filter the list with the `baseName` query\nparameter to retrieve one group."},"supportedBy":{"type":"object","description":"Field configurations for each resource type involved in trading\npartner onboarding.","properties":{"ediProfile":{"$ref":"#/components/schemas/SupportedBySection"},"export":{"$ref":"#/components/schemas/SupportedBySection"},"import":{"$ref":"#/components/schemas/SupportedBySection"},"connection":{"$ref":"#/components/schemas/ConnectionSupportedBySection"}}}}},"SupportedBySection":{"type":"object","description":"Conditions, pre-configured field values, and fields the user must set\nfor a resource type (export, import, or EDI profile) during trading\npartner onboarding.","properties":{"conditions":{"type":"array","description":"Expression-based filters referenced by `_conditionIds` in\n`preConfiguredFields` and `fieldsUserMustSet`.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields set to predefined values during onboarding. In an EDI profile section, a value for\nyour own identity (`myInterchangeId`, `myGroupId`) or a placeholder partner ID such as\n`XXXXXXXXXXXXXXX` is a template stand-in, not a real value; the real IDs are among the\nfields the user must set.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide values for during onboarding.","items":{"$ref":"#/components/schemas/FieldUserMustSet"}}}},"Filter":{"type":"object","description":"Configuration for selectively processing records based on specified criteria. This object enables\nprecise control over which items are included or excluded from processing operations.\n\n**Filter behavior**\n\nWhen configured, the filter is applied before processing begins:\n- Items that match the filter criteria are processed\n- Items that don't match are completely skipped\n- No partial processing is performed\n\nSend the whole object. A rules array sent alone as the `filter` value is not\nstored, and a full update of an export that carries one removes the filter the\nexport had, with no error.\n\n**Implementation approaches**\n\nThere are two distinct filtering mechanisms available:\n\n**Rule-Based Filtering (`type: \"expression\"`)**\n- **Best For**: Common filtering patterns based on standard attributes\n- **Capabilities**: Filter by names, values, dates, numerical ranges, text patterns\n- **Advantages**: Declarative, no coding required, consistent performance\n- **Configuration**: Define rules in the `expression` object\n- **Use When**: You have clear, static criteria for selection\n\n**Script-Based Filtering (`type: \"script\"`)**\n- **Best For**: Complex logic, dynamic criteria, or business rules\n- **Capabilities**: Full programmatic control, access to complete metadata\n- **Advantages**: Maximum flexibility, can implement any filtering logic\n- **Configuration**: Reference a script in the `script` object\n- **Use When**: Simple rules aren't sufficient or logic needs to be dynamic\n","properties":{"type":{"type":"string","description":"Determines which filtering mechanism to use. This choice affects which properties\nmust be configured and how filtering logic is implemented.\n\n**Available types**\n\n**Rule-Based Filtering (`\"expression\"`)**\n- **Required Config**: The `expression` object with rule definitions\n- **Behavior**: Evaluates declarative rules against item attributes\n- **Best For**: Common patterns like name matching, date ranges, value limits\n- **Advantages**: Simpler to configure, no custom code required\n\n**Script-Based Filtering (`\"script\"`)**\n- **Required Config**: The `script` object with _scriptId and function\n- **Behavior**: Executes custom JavaScript to determine which items to process\n- **Best For**: Complex conditions, business logic, dynamic criteria\n- **Advantages**: Maximum flexibility, can implement any logic\n\n**Implementation guidance**\n\n1. For standard filtering needs (name, size, date), use `\"expression\"`\n2. For complex logic or conditions not covered by expressions, use `\"script\"`\n3. When selecting a type, you must configure the corresponding object:\n    - `type: \"expression\"` requires the `expression` object\n    - `type: \"script\"` requires the `script` object\n","enum":["expression","script"]},"expression":{"type":"object","description":"Configuration for declarative rule-based filtering. This object enables filtering\nitems based on common attributes without requiring custom code.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"expression\" and should not be\nconfigured otherwise. It provides a standardized way to define filtering rules that\ncan match against item attributes like name, type, value, date, and other properties.\n\n**Implementation guidance**\n\nThe expression system uses a rule-based approach where:\n- Rules can be combined with AND/OR logic\n- Each rule can check a specific attribute\n- Multiple conditions can be applied (ranges, pattern matching, exact matches)\n\n**Common filter patterns**\n\n1. **Pattern matching**: Regular expressions with `matches`\n2. **Value range filtering**: Numbers between min and max values\n3. **Date range filtering**: Items created/modified within specific time ranges\n4. **Status checking**: Items with specific status values or properties\n\nFor AI agents: Rule-based filtering should be your first choice when the filtering criteria\ncan be expressed in terms of standard attributes. Only use script-based filtering when\nmore complex logic is required.\n","properties":{"version":{"type":"string","description":"Version identifier for the expression format. Currently only version \"1\" is supported.\n\nThis field ensures future compatibility if the expression format evolves. Always set to \"1\"\nfor current implementations.\n","enum":["1"]},"rules":{"type":"array","description":"Expression array defining filter conditions using prefix notation. The first element is the operator,\nfollowed by its operands which may themselves be nested expression arrays.\n\nThe rule expression follows this pattern:\n- First element: Operator name (string)\n- Remaining elements: Operands for that operator (values or nested expressions)\n\n**Expression structure**\n\nFilter expressions use a prefix notation where operators appear before their operands:\n```\n[operator, operand1, operand2, ...]\n```\n\n**Comparison Operators**\n- `\"equals\"`: Exact match (equals)\n- `\"notequals\"`: Not equal to value (not equals)\n- `\"greaterthan\"`: Value is greater than specified value (is greater than)\n- `\"greaterthanequals\"`: Value is greater than or equal to specified value (is greater than or equals)\n- `\"lessthan\"`: Value is less than specified value (is less than)\n- `\"lessthanequals\"`: Value is less than or equal to specified value (is less than or equals)\n- `\"startswith\"`: String starts with specified prefix (starts with)\n- `\"notstartswith\"`: String does not start with specified prefix (does not start with)\n- `\"endswith\"`: String ends with specified suffix (ends with)\n- `\"notendswith\"`: String does not end with specified suffix (does not end with)\n- `\"contains\"`: String contains specified substring (contains)\n- `\"doesnotcontain\"`: String does not contain specified substring (does not contain)\n- `\"empty\"`: Field is missing or empty (is empty)\n- `\"notempty\"`: Field contains a value (is not empty)\n- `\"matches\"`: Matches a regular expression, ignoring case (matches)\n\nOperator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored\nas sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,\n`doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:\nthey are refused with 422 \"Invalid operation: <name>\", with the name in lowercase,\nboth when the filter is saved and by `POST /v1/processors/filter`. To negate a\ncondition, wrap it in `not`.\n\nThe string comparisons (`equals`, `contains`, `startswith`, `endswith` and their\nnegations) are case-sensitive; wrap the field in `lowercase` to compare without case.\n`matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also\nmatches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`\nmakes the pattern invalid. The filter still saves, but in a run every record fails\nwith `FILTER_EVALUATION_FAILED` (\"Invalid regular expression: /(?i)…/gi: Invalid\ngroup\"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified\n2026-10-22).\n\n**Logical Operators**\n- `\"and\"`: All conditions must be true\n- `\"or\"`: At least one condition must be true\n- `\"not\"`: Negates the condition\n\n**Field Access and Type Conversion**\n- `\"extract\"`: Access a field from the item by name\n- `\"settings\"`: Access a custom setting from the flow, flow step, or integration configuration\n- `\"boolean\"`: Convert value to Boolean type\n- `\"epochtime\"`: Convert value to Epoch Time (Unix timestamp)\n- `\"number\"`: Convert value to Number type\n- `\"string\"`: Convert value to String type\n\n**Field Access Details**\n\n**Using `extract` to access record fields:**\n- Retrieves values from the current record being processed\n- Can access nested properties using dot notation (e.g., `\"customer.email\"`)\n- Paths are relative to the record itself: `[\"extract\", \"record.status\"]`\n  matches nothing\n- In a record filter, must be wrapped in a type conversion (`string`, `number`,\n  `boolean` or `epochtime`): a bare `[\"extract\", ...]` operand is refused with 422\n  \"Field operation extract must be called by a Type Conversion Operation but was called\n  by <operator>\", both when an import's filter is saved and by\n  `POST /v1/processors/filter`\n\n**Using `settings` to access configuration values:**\n- Retrieves values from the integration's configuration settings\n- Supports different scopes with prefix notation:\n  - `flow.settingName`: Access flow-level settings\n  - `flowGrouping.settingName`: Access the flow group's settings\n  - `export.settingName`: Access the export's (or lookup's) own settings\n  - `import.settingName`: Access the import's own settings\n  - `integration.settingName`: Access integration-level settings\n  - `connection.settingName`, `iClient.settingName`: Access the step's\n    connection and iClient settings\n- A scope whose resource has no settings can be absent; a rule that reads\n  it matches nothing\n- Must be wrapped in a type conversion like `extract`: a bare\n  `[\"settings\", ...]` operand is refused with 422 \"Field operation settings\n  must be called by a Type Conversion Operation\"\n- Useful for dynamic filtering based on configuration\n\n**Field Transformations**\n- `\"lowercase\"`: Convert string to lowercase\n- `\"uppercase\"`: Convert string to uppercase\n- `\"ceiling\"`: Round number up to the nearest integer\n- `\"floor\"`: Round number down to the nearest integer\n- `\"abs\"`: Get absolute value of a number\n\n**Arithmetic** (number operands)\n- `\"add\"`, `\"subtract\"`, `\"multiply\"`, `\"divide\"`, `\"modulo\"`: for example\n  `[\"subtract\", [\"number\", [\"extract\", \"total\"]], [\"number\", [\"extract\", \"discount\"]]]`.\n  `mod` is not an operator (422 \"Invalid operation: mod.\").\n\n**Dates**\n- `epochtime` reads ISO 8601 strings and epoch-millisecond numbers. An empty\n  string, a string that isn't a date, or epoch milliseconds sent as a string\n  fail it with \"Invalid date. Cannot convert given string or number to date\n  time.\", followed by `; record=` and the record as JSON: in a run that record fails (`FILTER_EVALUATION_FAILED`, source\n  `output_filter` on an export), and `POST /v1/processors/filter` and an\n  export preview refuse the whole call with 422. `and` and `or` evaluate\n  every operand, so a `notempty` test beside it doesn't prevent the failure.\n  A missing or null field doesn't match.\n- `datetime`, `date` and `timestamp` are not type conversions: 422\n  \"Invalid operation: <name>.\"\n- `number` reads a missing or empty field as 0.\n\n**Handlebars operands**\n- An operand can also be a string holding exactly one Handlebars expression, such as\n  `\"{{record.status}}\"` or `\"{{lowercase record.code}}\"`, on either side of the\n  operator. It renders against the record (`record.<field>`; an unprefixed\n  `{{status}}` renders empty) before the comparison.\n- The rendered value is a string: wrap it in `[\"number\", ...]` to compare it with a\n  number, or the rule is refused with 422.\n- `epochtime` does not render Handlebars: `[\"epochtime\", \"{{timestamp}}\"]` is refused\n  with 422 \"invalid datetime format\".\n- A string with text around the expression, or with more than one expression, is\n  compared as a literal.\n- `[\"number\", \"{{timestamp \\\"x\\\"}}\"]` is the current time in epoch milliseconds,\n  so `[\"greaterthanequals\", [\"epochtime\", [\"extract\", \"created\"]], [\"subtract\",\n  [\"number\", \"{{timestamp \\\"x\\\"}}\"], 604800000]]` keeps records created in the\n  last 7 days.\n- An unknown helper fails the rule with 422 \"Failed to evaluate handlebars\n  expression\".\n\nChoose the type conversion that matches the comparison — `number` for numeric\ncomparisons, `epochtime` for dates, `string` for text. For example:\n\n```json\n[\n  \"equals\",\n  [\n    \"number\",  // Convert to number before comparison\n    [\n      \"extract\",\n      \"quantity\"\n    ]\n  ],\n  100\n]\n```\n\nExample with datetime conversion:\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",  // Convert to Unix timestamp before comparison\n    [\n      \"extract\",\n      \"createdDate\"\n    ]\n  ],\n  1609459200000  // January 1, 2021 as Unix timestamp in milliseconds\n]\n```\n\nExample with transformations:\n```json\n[\n  \"and\",\n  [\n    \"matches\",\n    [\n      \"lowercase\",  // Convert to lowercase before matching\n      [\n        \"string\",\n        [\n          \"extract\",\n          \"categories\"\n        ]\n      ]\n    ],\n    \"netsuite\"\n  ],\n  [\n    \"notequals\",\n    [\n      \"string\",\n      [\n        \"extract\",\n        \"recurrence.pattern.type\"\n      ]\n    ],\n    \"\"\n  ]\n]\n```\n\nExample comparing a record field with a flow setting:\n```json\n[\n  \"equals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"trantype\"\n    ]\n  ],\n  [\n    \"string\",\n    [\n      \"settings\",\n      \"flow.trantype\"\n    ]\n  ]\n]\n```\n\n**Examples**\n\nExample 1: Status field is not equal to \"cancelled\"\n```json\n[\n  \"notequals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"status\"\n    ]\n  ],\n  \"cancelled\"\n]\n```\n\nExample 2: Filename starts with \"HC\"\n```json\n[\n  \"startswith\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"filename\"\n    ]\n  ],\n  \"HC\"\n]\n```\n\nExample 3: Amount is greater than 100\n```json\n[\n  \"greaterthan\",\n  [\n    \"number\",\n    [\n      \"extract\",\n      \"amount\"\n    ]\n  ],\n  100\n]\n```\n\nExample 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`\nagainst epoch milliseconds: a `string` comparison of ISO timestamps orders values with\ndifferent UTC offsets wrongly.\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",\n    [\n      \"extract\",\n      \"orderDate\"\n    ]\n  ],\n  1672531200000\n]\n```\n","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"},{"title":"Array","type":"array"},{"title":"Null","type":"null"}]}}}},"script":{"type":"object","description":"Configuration for programmable script-based filtering. This object enables complex, custom\nfiltering logic beyond what expression-based filtering can provide.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"script\" and should not be configured\notherwise. It provides a way to execute custom JavaScript code to determine which items\nshould be processed.\n\n**Implementation approach**\n\nScript-based filtering works by:\n1. Executing the specified function from the referenced script\n2. Passing item data to the function\n3. Using the function's return value (true/false) to determine inclusion\n\n**Common use cases**\n\nScript filtering is ideal for:\n- Complex business logic that can't be expressed as simple rules\n- Dynamic filtering criteria that change based on external factors\n- Content-based filtering that requires deep inspection\n- Advanced pattern matching beyond simple wildcards\n- Multi-stage filtering with intermediate logic\n\nFor AI agents: Only use script-based filtering when expression-based filtering is insufficient.\nScript filtering requires maintaining custom code, which adds complexity to the integration.\n","properties":{"_scriptId":{"type":"string","description":"Reference to the Script resource that contains the filtering logic. This must be a valid\nObjectId of a Script resource in this account: any other id fails the save with 422\n(\"Only a script owned by the user or a script shared by the Integration App can be used\nat filter.script._scriptId.\").\n\nThe referenced script must contain the function specified in the `function` field\nand must be written to handle filtering specifically. The script receives\nitem data as its input and must return a boolean value indicating whether\nto process the item (true) or skip it (false).\n\nFormat: 24-character hexadecimal string (MongoDB ObjectId)\n"},"function":{"type":"string","description":"Name of the function within the script to execute for filtering decisions. This function\nmust exist in the script referenced by _scriptId.\n\n**Function requirements**\n\nThe specified function must:\n- Accept item data as its first parameter\n- Return a boolean value (true to process the item, false to skip it)\n- Handle errors gracefully\n- Execute efficiently (as it may run for many items)\n\n**Function signature**\n\n```javascript\nfunction filterItems(itemData) {\n  // itemData contains properties of the item being evaluated\n  // Custom logic here\n  return true; // or false to skip the item\n}\n```\n\nFor AI agents: Ensure the function name exactly matches a function defined in the\nreferenced script, as mismatches will cause the filter to fail.\n"}}}}},"PreConfiguredField":{"type":"object","description":"A field automatically set to a predefined value during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource."},"values":{"type":"array","description":"Value(s) to assign. Typically a single-element array.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply. If absent, always applies.","items":{"type":"string","format":"objectId"}}}},"FieldUserMustSet":{"type":"object","description":"A field the user must provide during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource, or the field's form label: EDI\nprofile sections commonly name fields by label (for example the trading partner\ninterchange ID), so map a label to its profile field before checking it."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI instead of the default."}}},"ConnectionSupportedBySection":{"type":"object","description":"Connection-specific section. Same as other `supportedBy` sections but\n`fieldsUserMustSet` entries may include `inputType` to control the UI\ninput widget.","properties":{"conditions":{"type":"array","description":"Expression-based filters for the connection section.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields automatically set on the connection during onboarding. Apart from the transport\n`type`, treat them as template stand-ins (published connectors carry values such as a\nplaceholder AS2 partner ID and a staging AS2 URI), not the partner's real settings; the\npartner's host and identity are in `fieldsUserMustSet`.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide for the connection.","items":{"$ref":"#/components/schemas/ConnectionFieldUserMustSet"}}}},"ConnectionFieldUserMustSet":{"type":"object","description":"Connection field the user must provide during onboarding. Adds\n`inputType` to control the UI input widget.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"inputType":{"type":"string","enum":["number","password","uri"],"description":"UI input widget type for this field."},"path":{"type":"string","description":"Dot-notation path of the field on the connection."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/tpconnectors/{_id}":{"get":{"summary":"Get a trading partner connector","description":"Returns the complete configuration of a trading partner connector,\nincluding all `supportedBy` sections. Unpublished connectors are\nonly visible to their owner. The list endpoint returns a summary\nthat omits `published` and `supportedBy`.","operationId":"getTradingPartnerConnectorById","tags":["Trading Partner Connectors"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the trading partner connector.","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Trading partner connector retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingPartnerConnector"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
````

## Update a trading partner connector

> Replaces an existing trading partner connector (a full replace). Create\
> connectors with \`POST /v1/tpconnectors\`. When \`published\` is set to\
> \`true\`, the \`supportedBy\` sections are validated for required fields.

````json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"tags":[{"name":"Trading Partner Connectors","description":"Trading partner connectors are reusable templates for onboarding EDI\ntrading partners. Each connector defines pre-configured field values\nand fields the user must set for connections, exports, imports, and\nEDI profiles.\n\nConnectors support expression-based conditions that control when\ncertain field configurations apply. Publishing a connector makes it\navailable to all accounts but requires the\n`allowedToPublishTPConnectors` permission.\n\n## Trading partner connector schema\n\n{% openapi-schemas spec=\"tradingpartnerconnector\" schemas=\"TradingPartnerConnector\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Request schema for creating or updating a trading partner connector.\nOnly `name` is required for creation. Connection\n`preConfiguredFields` must include a `type` path (e.g. `ftp` or\n`as2`) and export/import must include `file.type` set to\n`filedefinition` -- these are validated when `published` is `true`.\n\n`type`, `region`, and `model` must match the deployment's configured\nvalues exactly, including case. A value outside the list is not\nrejected with a validation error: the request never completes (no\nresponse is returned) and nothing is created or changed.","required":["name"],"allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"}]},"TradingPartnerConnectorBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","description":"Connector name. Must be unique across all published connectors."},"published":{"type":"boolean","default":false,"description":"Whether this connector is published and available platform-wide.\nRequires the `allowedToPublishTPConnectors` permission — without\nit, this field is silently ignored."},"helpURL":{"type":"string","anyOf":[{"format":"uri"},{"const":""}],"description":"URL to documentation for this trading partner connector. May be an\nempty string when no documentation link exists."},"type":{"type":"string","description":"Categorizes the connector by the transport its templates configure.\nAllowed values are configured per deployment — `FTP`, `AS2`, and `S3`\nby default. Absent from responses when never set (connectors created\nbefore this field existed omit it)."},"region":{"type":"string","description":"Geographic region the trading partner operates in, used to group\nconnectors in the catalog. Defaults to `North America` at creation\nwhen omitted; allowed values are configured per deployment (`North\nAmerica`, `European Union`, `Canada`, `USA`, and `Australia` by\ndefault). Connectors created before this field existed omit it."},"model":{"type":"string","description":"Business-model variant of the trading partner relationship, such as\n`Dropship`, `Warehouse`, or `DVS`. Defaults to `none` at creation when\nomitted, meaning the connector has no business-model variant; allowed\nvalues are configured per deployment. Connectors created before this\nfield existed omit it."},"baseName":{"type":"string","description":"Shared base name that groups related connector variants for the same\ntrading partner — for example, a partner's AS2 and FTP connectors.\nOnly present when set. Filter the list with the `baseName` query\nparameter to retrieve one group."},"supportedBy":{"type":"object","description":"Field configurations for each resource type involved in trading\npartner onboarding.","properties":{"ediProfile":{"$ref":"#/components/schemas/SupportedBySection"},"export":{"$ref":"#/components/schemas/SupportedBySection"},"import":{"$ref":"#/components/schemas/SupportedBySection"},"connection":{"$ref":"#/components/schemas/ConnectionSupportedBySection"}}}}},"SupportedBySection":{"type":"object","description":"Conditions, pre-configured field values, and fields the user must set\nfor a resource type (export, import, or EDI profile) during trading\npartner onboarding.","properties":{"conditions":{"type":"array","description":"Expression-based filters referenced by `_conditionIds` in\n`preConfiguredFields` and `fieldsUserMustSet`.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields set to predefined values during onboarding. In an EDI profile section, a value for\nyour own identity (`myInterchangeId`, `myGroupId`) or a placeholder partner ID such as\n`XXXXXXXXXXXXXXX` is a template stand-in, not a real value; the real IDs are among the\nfields the user must set.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide values for during onboarding.","items":{"$ref":"#/components/schemas/FieldUserMustSet"}}}},"Filter":{"type":"object","description":"Configuration for selectively processing records based on specified criteria. This object enables\nprecise control over which items are included or excluded from processing operations.\n\n**Filter behavior**\n\nWhen configured, the filter is applied before processing begins:\n- Items that match the filter criteria are processed\n- Items that don't match are completely skipped\n- No partial processing is performed\n\nSend the whole object. A rules array sent alone as the `filter` value is not\nstored, and a full update of an export that carries one removes the filter the\nexport had, with no error.\n\n**Implementation approaches**\n\nThere are two distinct filtering mechanisms available:\n\n**Rule-Based Filtering (`type: \"expression\"`)**\n- **Best For**: Common filtering patterns based on standard attributes\n- **Capabilities**: Filter by names, values, dates, numerical ranges, text patterns\n- **Advantages**: Declarative, no coding required, consistent performance\n- **Configuration**: Define rules in the `expression` object\n- **Use When**: You have clear, static criteria for selection\n\n**Script-Based Filtering (`type: \"script\"`)**\n- **Best For**: Complex logic, dynamic criteria, or business rules\n- **Capabilities**: Full programmatic control, access to complete metadata\n- **Advantages**: Maximum flexibility, can implement any filtering logic\n- **Configuration**: Reference a script in the `script` object\n- **Use When**: Simple rules aren't sufficient or logic needs to be dynamic\n","properties":{"type":{"type":"string","description":"Determines which filtering mechanism to use. This choice affects which properties\nmust be configured and how filtering logic is implemented.\n\n**Available types**\n\n**Rule-Based Filtering (`\"expression\"`)**\n- **Required Config**: The `expression` object with rule definitions\n- **Behavior**: Evaluates declarative rules against item attributes\n- **Best For**: Common patterns like name matching, date ranges, value limits\n- **Advantages**: Simpler to configure, no custom code required\n\n**Script-Based Filtering (`\"script\"`)**\n- **Required Config**: The `script` object with _scriptId and function\n- **Behavior**: Executes custom JavaScript to determine which items to process\n- **Best For**: Complex conditions, business logic, dynamic criteria\n- **Advantages**: Maximum flexibility, can implement any logic\n\n**Implementation guidance**\n\n1. For standard filtering needs (name, size, date), use `\"expression\"`\n2. For complex logic or conditions not covered by expressions, use `\"script\"`\n3. When selecting a type, you must configure the corresponding object:\n    - `type: \"expression\"` requires the `expression` object\n    - `type: \"script\"` requires the `script` object\n","enum":["expression","script"]},"expression":{"type":"object","description":"Configuration for declarative rule-based filtering. This object enables filtering\nitems based on common attributes without requiring custom code.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"expression\" and should not be\nconfigured otherwise. It provides a standardized way to define filtering rules that\ncan match against item attributes like name, type, value, date, and other properties.\n\n**Implementation guidance**\n\nThe expression system uses a rule-based approach where:\n- Rules can be combined with AND/OR logic\n- Each rule can check a specific attribute\n- Multiple conditions can be applied (ranges, pattern matching, exact matches)\n\n**Common filter patterns**\n\n1. **Pattern matching**: Regular expressions with `matches`\n2. **Value range filtering**: Numbers between min and max values\n3. **Date range filtering**: Items created/modified within specific time ranges\n4. **Status checking**: Items with specific status values or properties\n\nFor AI agents: Rule-based filtering should be your first choice when the filtering criteria\ncan be expressed in terms of standard attributes. Only use script-based filtering when\nmore complex logic is required.\n","properties":{"version":{"type":"string","description":"Version identifier for the expression format. Currently only version \"1\" is supported.\n\nThis field ensures future compatibility if the expression format evolves. Always set to \"1\"\nfor current implementations.\n","enum":["1"]},"rules":{"type":"array","description":"Expression array defining filter conditions using prefix notation. The first element is the operator,\nfollowed by its operands which may themselves be nested expression arrays.\n\nThe rule expression follows this pattern:\n- First element: Operator name (string)\n- Remaining elements: Operands for that operator (values or nested expressions)\n\n**Expression structure**\n\nFilter expressions use a prefix notation where operators appear before their operands:\n```\n[operator, operand1, operand2, ...]\n```\n\n**Comparison Operators**\n- `\"equals\"`: Exact match (equals)\n- `\"notequals\"`: Not equal to value (not equals)\n- `\"greaterthan\"`: Value is greater than specified value (is greater than)\n- `\"greaterthanequals\"`: Value is greater than or equal to specified value (is greater than or equals)\n- `\"lessthan\"`: Value is less than specified value (is less than)\n- `\"lessthanequals\"`: Value is less than or equal to specified value (is less than or equals)\n- `\"startswith\"`: String starts with specified prefix (starts with)\n- `\"notstartswith\"`: String does not start with specified prefix (does not start with)\n- `\"endswith\"`: String ends with specified suffix (ends with)\n- `\"notendswith\"`: String does not end with specified suffix (does not end with)\n- `\"contains\"`: String contains specified substring (contains)\n- `\"doesnotcontain\"`: String does not contain specified substring (does not contain)\n- `\"empty\"`: Field is missing or empty (is empty)\n- `\"notempty\"`: Field contains a value (is not empty)\n- `\"matches\"`: Matches a regular expression, ignoring case (matches)\n\nOperator names are case-insensitive: `NOTEMPTY` and `endsWith` work and are stored\nas sent. `isempty`, `isnotempty`, `anyof`, `notcontains`, `doesnotstartwith`,\n`doesnotendwith`, `notmatches`, `doesnotmatch` and `notequal` are not operators:\nthey are refused with 422 \"Invalid operation: <name>\", with the name in lowercase,\nboth when the filter is saved and by `POST /v1/processors/filter`. To negate a\ncondition, wrap it in `not`.\n\nThe string comparisons (`equals`, `contains`, `startswith`, `endswith` and their\nnegations) are case-sensitive; wrap the field in `lowercase` to compare without case.\n`matches` is not: every pattern is compiled with the flags `gi`, so `^paid$` also\nmatches `PAID` and `[a-z]` matches capital letters. An inline flag such as `(?i)`\nmakes the pattern invalid. The filter still saves, but in a run every record fails\nwith `FILTER_EVALUATION_FAILED` (\"Invalid regular expression: /(?i)…/gi: Invalid\ngroup\"), and `POST /v1/processors/filter` refuses the call with 422 (live-verified\n2026-10-22).\n\n**Logical Operators**\n- `\"and\"`: All conditions must be true\n- `\"or\"`: At least one condition must be true\n- `\"not\"`: Negates the condition\n\n**Field Access and Type Conversion**\n- `\"extract\"`: Access a field from the item by name\n- `\"settings\"`: Access a custom setting from the flow, flow step, or integration configuration\n- `\"boolean\"`: Convert value to Boolean type\n- `\"epochtime\"`: Convert value to Epoch Time (Unix timestamp)\n- `\"number\"`: Convert value to Number type\n- `\"string\"`: Convert value to String type\n\n**Field Access Details**\n\n**Using `extract` to access record fields:**\n- Retrieves values from the current record being processed\n- Can access nested properties using dot notation (e.g., `\"customer.email\"`)\n- Paths are relative to the record itself: `[\"extract\", \"record.status\"]`\n  matches nothing\n- In a record filter, must be wrapped in a type conversion (`string`, `number`,\n  `boolean` or `epochtime`): a bare `[\"extract\", ...]` operand is refused with 422\n  \"Field operation extract must be called by a Type Conversion Operation but was called\n  by <operator>\", both when an import's filter is saved and by\n  `POST /v1/processors/filter`\n\n**Using `settings` to access configuration values:**\n- Retrieves values from the integration's configuration settings\n- Supports different scopes with prefix notation:\n  - `flow.settingName`: Access flow-level settings\n  - `flowGrouping.settingName`: Access the flow group's settings\n  - `export.settingName`: Access the export's (or lookup's) own settings\n  - `import.settingName`: Access the import's own settings\n  - `integration.settingName`: Access integration-level settings\n  - `connection.settingName`, `iClient.settingName`: Access the step's\n    connection and iClient settings\n- A scope whose resource has no settings can be absent; a rule that reads\n  it matches nothing\n- Must be wrapped in a type conversion like `extract`: a bare\n  `[\"settings\", ...]` operand is refused with 422 \"Field operation settings\n  must be called by a Type Conversion Operation\"\n- Useful for dynamic filtering based on configuration\n\n**Field Transformations**\n- `\"lowercase\"`: Convert string to lowercase\n- `\"uppercase\"`: Convert string to uppercase\n- `\"ceiling\"`: Round number up to the nearest integer\n- `\"floor\"`: Round number down to the nearest integer\n- `\"abs\"`: Get absolute value of a number\n\n**Arithmetic** (number operands)\n- `\"add\"`, `\"subtract\"`, `\"multiply\"`, `\"divide\"`, `\"modulo\"`: for example\n  `[\"subtract\", [\"number\", [\"extract\", \"total\"]], [\"number\", [\"extract\", \"discount\"]]]`.\n  `mod` is not an operator (422 \"Invalid operation: mod.\").\n\n**Dates**\n- `epochtime` reads ISO 8601 strings and epoch-millisecond numbers. An empty\n  string, a string that isn't a date, or epoch milliseconds sent as a string\n  fail it with \"Invalid date. Cannot convert given string or number to date\n  time.\", followed by `; record=` and the record as JSON: in a run that record fails (`FILTER_EVALUATION_FAILED`, source\n  `output_filter` on an export), and `POST /v1/processors/filter` and an\n  export preview refuse the whole call with 422. `and` and `or` evaluate\n  every operand, so a `notempty` test beside it doesn't prevent the failure.\n  A missing or null field doesn't match.\n- `datetime`, `date` and `timestamp` are not type conversions: 422\n  \"Invalid operation: <name>.\"\n- `number` reads a missing or empty field as 0.\n\n**Handlebars operands**\n- An operand can also be a string holding exactly one Handlebars expression, such as\n  `\"{{record.status}}\"` or `\"{{lowercase record.code}}\"`, on either side of the\n  operator. It renders against the record (`record.<field>`; an unprefixed\n  `{{status}}` renders empty) before the comparison.\n- The rendered value is a string: wrap it in `[\"number\", ...]` to compare it with a\n  number, or the rule is refused with 422.\n- `epochtime` does not render Handlebars: `[\"epochtime\", \"{{timestamp}}\"]` is refused\n  with 422 \"invalid datetime format\".\n- A string with text around the expression, or with more than one expression, is\n  compared as a literal.\n- `[\"number\", \"{{timestamp \\\"x\\\"}}\"]` is the current time in epoch milliseconds,\n  so `[\"greaterthanequals\", [\"epochtime\", [\"extract\", \"created\"]], [\"subtract\",\n  [\"number\", \"{{timestamp \\\"x\\\"}}\"], 604800000]]` keeps records created in the\n  last 7 days.\n- An unknown helper fails the rule with 422 \"Failed to evaluate handlebars\n  expression\".\n\nChoose the type conversion that matches the comparison — `number` for numeric\ncomparisons, `epochtime` for dates, `string` for text. For example:\n\n```json\n[\n  \"equals\",\n  [\n    \"number\",  // Convert to number before comparison\n    [\n      \"extract\",\n      \"quantity\"\n    ]\n  ],\n  100\n]\n```\n\nExample with datetime conversion:\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",  // Convert to Unix timestamp before comparison\n    [\n      \"extract\",\n      \"createdDate\"\n    ]\n  ],\n  1609459200000  // January 1, 2021 as Unix timestamp in milliseconds\n]\n```\n\nExample with transformations:\n```json\n[\n  \"and\",\n  [\n    \"matches\",\n    [\n      \"lowercase\",  // Convert to lowercase before matching\n      [\n        \"string\",\n        [\n          \"extract\",\n          \"categories\"\n        ]\n      ]\n    ],\n    \"netsuite\"\n  ],\n  [\n    \"notequals\",\n    [\n      \"string\",\n      [\n        \"extract\",\n        \"recurrence.pattern.type\"\n      ]\n    ],\n    \"\"\n  ]\n]\n```\n\nExample comparing a record field with a flow setting:\n```json\n[\n  \"equals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"trantype\"\n    ]\n  ],\n  [\n    \"string\",\n    [\n      \"settings\",\n      \"flow.trantype\"\n    ]\n  ]\n]\n```\n\n**Examples**\n\nExample 1: Status field is not equal to \"cancelled\"\n```json\n[\n  \"notequals\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"status\"\n    ]\n  ],\n  \"cancelled\"\n]\n```\n\nExample 2: Filename starts with \"HC\"\n```json\n[\n  \"startswith\",\n  [\n    \"string\",\n    [\n      \"extract\",\n      \"filename\"\n    ]\n  ],\n  \"HC\"\n]\n```\n\nExample 3: Amount is greater than 100\n```json\n[\n  \"greaterthan\",\n  [\n    \"number\",\n    [\n      \"extract\",\n      \"amount\"\n    ]\n  ],\n  100\n]\n```\n\nExample 4: Order date is after January 1, 2023 (UTC). Compare dates as `epochtime`\nagainst epoch milliseconds: a `string` comparison of ISO timestamps orders values with\ndifferent UTC offsets wrongly.\n```json\n[\n  \"greaterthan\",\n  [\n    \"epochtime\",\n    [\n      \"extract\",\n      \"orderDate\"\n    ]\n  ],\n  1672531200000\n]\n```\n","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"},{"title":"Array","type":"array"},{"title":"Null","type":"null"}]}}}},"script":{"type":"object","description":"Configuration for programmable script-based filtering. This object enables complex, custom\nfiltering logic beyond what expression-based filtering can provide.\n\n**Usage context**\n\nThis object is REQUIRED when `filter.type` is set to \"script\" and should not be configured\notherwise. It provides a way to execute custom JavaScript code to determine which items\nshould be processed.\n\n**Implementation approach**\n\nScript-based filtering works by:\n1. Executing the specified function from the referenced script\n2. Passing item data to the function\n3. Using the function's return value (true/false) to determine inclusion\n\n**Common use cases**\n\nScript filtering is ideal for:\n- Complex business logic that can't be expressed as simple rules\n- Dynamic filtering criteria that change based on external factors\n- Content-based filtering that requires deep inspection\n- Advanced pattern matching beyond simple wildcards\n- Multi-stage filtering with intermediate logic\n\nFor AI agents: Only use script-based filtering when expression-based filtering is insufficient.\nScript filtering requires maintaining custom code, which adds complexity to the integration.\n","properties":{"_scriptId":{"type":"string","description":"Reference to the Script resource that contains the filtering logic. This must be a valid\nObjectId of a Script resource in this account: any other id fails the save with 422\n(\"Only a script owned by the user or a script shared by the Integration App can be used\nat filter.script._scriptId.\").\n\nThe referenced script must contain the function specified in the `function` field\nand must be written to handle filtering specifically. The script receives\nitem data as its input and must return a boolean value indicating whether\nto process the item (true) or skip it (false).\n\nFormat: 24-character hexadecimal string (MongoDB ObjectId)\n"},"function":{"type":"string","description":"Name of the function within the script to execute for filtering decisions. This function\nmust exist in the script referenced by _scriptId.\n\n**Function requirements**\n\nThe specified function must:\n- Accept item data as its first parameter\n- Return a boolean value (true to process the item, false to skip it)\n- Handle errors gracefully\n- Execute efficiently (as it may run for many items)\n\n**Function signature**\n\n```javascript\nfunction filterItems(itemData) {\n  // itemData contains properties of the item being evaluated\n  // Custom logic here\n  return true; // or false to skip the item\n}\n```\n\nFor AI agents: Ensure the function name exactly matches a function defined in the\nreferenced script, as mismatches will cause the filter to fail.\n"}}}}},"PreConfiguredField":{"type":"object","description":"A field automatically set to a predefined value during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource."},"values":{"type":"array","description":"Value(s) to assign. Typically a single-element array.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply. If absent, always applies.","items":{"type":"string","format":"objectId"}}}},"FieldUserMustSet":{"type":"object","description":"A field the user must provide during onboarding.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"path":{"type":"string","description":"Dot-notation path of the field on the target resource, or the field's form label: EDI\nprofile sections commonly name fields by label (for example the trading partner\ninterchange ID), so map a label to its profile field before checking it."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI instead of the default."}}},"ConnectionSupportedBySection":{"type":"object","description":"Connection-specific section. Same as other `supportedBy` sections but\n`fieldsUserMustSet` entries may include `inputType` to control the UI\ninput widget.","properties":{"conditions":{"type":"array","description":"Expression-based filters for the connection section.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Referenced by `_conditionIds` in field entries."},"condition":{"$ref":"#/components/schemas/Filter"}}}},"preConfiguredFields":{"type":"array","description":"Fields automatically set on the connection during onboarding. Apart from the transport\n`type`, treat them as template stand-ins (published connectors carry values such as a\nplaceholder AS2 partner ID and a staging AS2 URI), not the partner's real settings; the\npartner's host and identity are in `fieldsUserMustSet`.","items":{"$ref":"#/components/schemas/PreConfiguredField"}},"fieldsUserMustSet":{"type":"array","description":"Fields the user must provide for the connection.","items":{"$ref":"#/components/schemas/ConnectionFieldUserMustSet"}}}},"ConnectionFieldUserMustSet":{"type":"object","description":"Connection field the user must provide during onboarding. Adds\n`inputType` to control the UI input widget.","properties":{"_id":{"type":"string","format":"objectId","description":"Server-assigned subdocument ID, present on every stored entry.\nInclude it on updates to preserve entry identity."},"inputType":{"type":"string","enum":["number","password","uri"],"description":"UI input widget type for this field."},"path":{"type":"string","description":"Dot-notation path of the field on the connection."},"values":{"type":"array","description":"Optional suggested or constrained values.","items":{"oneOf":[{"title":"String","type":"string"},{"title":"Number","type":"number"},{"title":"Boolean","type":"boolean"},{"title":"Object","type":"object"}]}},"_conditionIds":{"type":"array","description":"Condition IDs that must be satisfied for this field to apply.","items":{"type":"string","format":"objectId"}},"helpURL":{"type":"string","format":"uri","description":"URL to documentation for this field."},"labelOverride":{"type":"string","description":"Custom label to display in the UI."}}},"TradingPartnerConnector":{"type":"object","required":["_id","_userId","name","createdAt","lastModified"],"description":"Trading partner connector with metadata. The list endpoint returns a\nsummary shape (omits `published` and `supportedBy` but includes `type`,\n`region`, `model`, and `baseName` when set); GET by ID returns the full\nconfiguration.","allOf":[{"$ref":"#/components/schemas/TradingPartnerConnectorBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns or created this trading partner connector."}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/tpconnectors/{_id}":{"put":{"summary":"Update a trading partner connector","description":"Replaces an existing trading partner connector (a full replace). Create\nconnectors with `POST /v1/tpconnectors`. When `published` is set to\n`true`, the `supportedBy` sections are validated for required fields.","operationId":"updateTradingPartnerConnector","tags":["Trading Partner Connectors"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the trading partner connector.","required":true,"schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"200":{"description":"Trading partner connector updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradingPartnerConnector"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
````

## Delete a trading partner connector

> Deletes a trading partner connector. The recycle bin doesn't take trading partner\
> connectors, so there is no route to restore a deleted one.

```json
{"openapi":"3.2.0","info":{"title":"Trading Partner Connectors","version":"1.0.0"},"tags":[{"name":"Trading Partner Connectors","description":"Trading partner connectors are reusable templates for onboarding EDI\ntrading partners. Each connector defines pre-configured field values\nand fields the user must set for connections, exports, imports, and\nEDI profiles.\n\nConnectors support expression-based conditions that control when\ncertain field configurations apply. Publishing a connector makes it\navailable to all accounts but requires the\n`allowedToPublishTPConnectors` permission.\n\n## Trading partner connector schema\n\n{% openapi-schemas spec=\"tradingpartnerconnector\" schemas=\"TradingPartnerConnector\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/tpconnectors/{_id}":{"delete":{"summary":"Delete a trading partner connector","description":"Deletes a trading partner connector. The recycle bin doesn't take trading partner\nconnectors, so there is no route to restore a deleted one.","operationId":"deleteTradingPartnerConnector","tags":["Trading Partner Connectors"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the trading partner connector.","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Trading partner connector deleted successfully."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```
