<!-- TIER:1 -- Configuring Connections A connection is a credential and configuration object that lets Celigo communicate with an external system. Every export and import references a connection via . Connections must be created before the resources that use them. Concerns when configuring a connection: - Authentication -- choosing the right auth method (OAuth, token, basic, key-pair, certificate, etc.) and providing the correct credentials - Concurrency -- how many parallel requests Celigo can make to the target system ( ). Can be shared across connections via - Health monitoring -- ping con…

\n description: |-\n External ID Celigo presents when assuming the role; must match the\n `sts:ExternalId` condition in the role's trust policy. Fixed at creation: a `PUT`\n that sends a different value keeps the stored one. A value outside the allowed\n character set or length fails with 422 `invalid_field_value`.\n examples: [\"celigo-7f3a9c2e1b\"]\n roleArn:\n type: string\n pattern: '^arn:[a-z-]+:iam::\\d{12}:role/[A-Za-z0-9+=,.@_/-]{1,576}

<!-- TIER:1 -- Configuring Connections A connection is a credential and configuration object that lets Celigo communicate with an external system. Every export and import references a connection via . Connections must be created before the resources that use them. Concerns when configuring a connection: - Authentication -- choosing the right auth method (OAuth, token, basic, key-pair, certificate, etc.) and providing the correct credentials - Concurrency -- how many parallel requests Celigo can make to the target system ( ). Can be shared across connections via - Health monitoring -- ping con…

\n description: |-\n ARN of the AWS IAM role to assume for cross-account access. Optional on the iClient\n (a malformed ARN fails with 422 `invalid_field_value`), but no connection in IAM-role\n mode can be saved against this iClient until it is set, and each connection family\n accepts only its own role-name prefix: `celigo-file-adaptor-` for Amazon S3,\n `celigo-data-warehouse-adaptor-` for Amazon Redshift, `celigo-http-adaptor-` for the\n AWS HTTP connectors (`auth.type` `awsiam`).\n x-celigo-ai-guidance:\n - |-\n Name the role for the connection family that will use this iClient:\n \"celigo-file-adaptor-\u003canything>\" for an S3 connection (s3.authType \"awsIam\"),\n \"celigo-data-warehouse-adaptor-\u003canything>\" for a Redshift connection\n (redshift.authType \"awsIam\"), \"celigo-http-adaptor-\u003canything>\" for an HTTP\n connection (auth.type \"awsiam\"). One iClient cannot serve two families.\n - |-\n While roleArn is unset, every IAM-mode connection save fails with 422\n missing_required_field \"Expected field: awsIam.roleArn to be present.\" on the\n connection's _iClientId field. With the wrong prefix the save fails with 422\n invalid_field_value: on HTTP \"HTTP IAM Role authentication requires awsIam.roleArn to\n reference a role name starting with celigo-http-adaptor-.\"; on S3 \"Invalid value for\n field \\\"_iClientId\\\": Your role ARN's name must begin with celigo-file-adaptor.\"; on\n Redshift \"Invalid value for field \\\"_iClientId\\\": Your role ARN's name must begin with\n celigo-data-warehouse-adaptor.\".\n examples:\n - \"arn:aws:iam::123456789012:role/celigo-http-adaptor-orders\"\n - \"arn:aws:iam::123456789012:role/celigo-file-adaptor-data-lake\"\n - \"arn:aws:iam::123456789012:role/celigo-data-warehouse-adaptor-analytics\"\n jwt:\n type: object\n description: |-\n JWT assertion configuration. Used when `enableJWT` is true to\n generate a signed JWT for inclusion in OAuth token requests via\n `{{{iClient.jwt.token}}}`.\n x-celigo-ai-guidance:\n - |-\n ## IMPLEMENTATION GUIDANCE:\n - Validate the JWT on the server side to ensure it is properly signed and not expired.\n - Use secure algorithms (e.g., RS256 or HS256) for signing the token.\n - Store sensitive information in the payload with caution, as JWTs can be decoded by clients.\n - Refresh tokens should be used to obtain new JWTs when the current one expires.\n - |-\n ## FIELD BEHAVIOR:\n - Must be a valid JWT string following the standard format: header.payload.signature.\n - Used to authenticate API requests and authorize access to specific endpoints.\n - Typically included in the Authorization header as a Bearer token.\n - Should have an expiration time to enhance security.\n - |-\n A JSON Web Token (JWT) used for securely transmitting information between\n parties as a JSON object.\n This token is typically used for authentication and authorization purposes,\n ensuring that the client has valid credentials to access protected resources.\n The JWT contains encoded header, payload,\n and signature sections that verify the token's integrity and authenticity.\n - |-\n ## IMPORTANT NOTES:\n - JWTs should be transmitted over secure channels (HTTPS) to prevent interception.\n - Do not store JWTs in insecure storage locations on the client side (e.g., localStorage) to avoid XSS attacks.\n - Always verify the token's signature and claims before granting access.\n - Be aware of token expiration and implement proper handling for expired tokens.\n - |-\n ## EXAMPLES:\n - eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.EXAMPLEpayload.EXAMPLEsignature\n - eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.EXAMPLEpayload.EXAMPLEsignature\n - |-\n ## DEPENDENCY CHAIN:\n - Depends on the authentication mechanism generating the JWT.\n - Requires a\n - |-\n A JSON Web Token (JWT) used for securely transmitting information between\n parties as a JSON object.\n This token is typically used for authentication and authorization purposes,\n ensuring that the client has valid credentials to access protected resources.\n The JWT contains encoded header, payload,\n and signature sections that verify the token's integrity and authenticity.\n - |-\n A JSON Web Token (JWT) used for securely transmitting information between\n parties as a JSON object.\n This token is typically used for authentication and authorization purposes,\n ensuring that the client has valid credentials to access protected resources.\n The JWT contains encoded header, payload,\n and signature sections that verify the token's integrity and authenticity.\n properties:\n signatureMethod:\n type: string\n enum:\n - hmac-sha256\n - hmac-sha384\n - hmac-sha512\n - rsa-sha256\n - rsa-sha384\n - rsa-sha512\n - es256\n - es384\n - es512\n - ps256\n - ps384\n - ps512\n x-enumDescriptions:\n hmac-sha256: HMAC with SHA-256 (symmetric); signs with secret.\n hmac-sha384: HMAC with SHA-384 (symmetric); signs with secret.\n hmac-sha512: HMAC with SHA-512 (symmetric); signs with secret.\n rsa-sha256: RSA with SHA-256 (asymmetric); signs with privateKey.\n rsa-sha384: RSA with SHA-384 (asymmetric); signs with privateKey.\n rsa-sha512: RSA with SHA-512 (asymmetric); signs with privateKey.\n es256: ECDSA with P-256 and SHA-256 (asymmetric); signs with privateKey.\n es384: ECDSA with P-384 and SHA-384 (asymmetric); signs with privateKey.\n es512: ECDSA with P-521 and SHA-512 (asymmetric); signs with privateKey.\n ps256: RSASSA-PSS with SHA-256 (asymmetric); signs with privateKey.\n ps384: RSASSA-PSS with SHA-384 (asymmetric); signs with privateKey.\n ps512: RSASSA-PSS with SHA-512 (asymmetric); signs with privateKey.\n description: |-\n Algorithm used to sign the JWT. HMAC methods sign with `secret`;\n RSA/ECDSA/PSS methods sign with `privateKey`.\n payload:\n description: |-\n JWT payload claims. Can be a JSON object or a stringified\n JSON template with Handlebars expressions.\n headers:\n description: |-\n JWT header claims. Can be a JSON object or a stringified\n JSON template with Handlebars expressions.\n privateKey:\n type: string\n description: |-\n Private key for signing the JWT. Returned masked as\n `\"******\"`. Re-send that value on update to keep it; it is not preserved if omitted.\n token:\n type: string\n readOnly: true\n description: |-\n Server-computed signed JWT token. Returned masked as\n `\"******\"` in responses.\n secret:\n type: string\n description: |-\n Shared secret for HMAC-based JWT signing (e.g. HS256).\n Returned masked as `\"******\"`. Re-send that value on update to\n keep it; it is not preserved if omitted.\n isSecretBase64Encoded:\n type: boolean\n description: When true, the `secret` value is Base64-encoded.\n # provider → credential sub-object. Only the awsIam branch is encoded so far (API-verified: an\n # awsIam iClient without the object fails with 422 \"The awsIam sub-schema is required\"); extend\n # this else-if chain (never allOf) as the other providers' requireds are live-verified.\n if:\n properties:\n provider:\n const: awsIam\n required: [provider]\n then:\n required: [awsIam]\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":206619,"content_sha256":"64a91463d8cf2ad890b39446d1ba6c19a9dd61d07d5ab15ded55e1cec290176f"},{"filename":"references/iclient-schemas/ebay.yml","content":"eBay:\n type: object\n description: eBay-specific iClient config for eBay developer program credentials\n properties:\n appId:\n type: string\n description: Application ID from the eBay Developer Program\n devId:\n type: string\n description: Developer ID from the eBay Developer Program\n certId:\n type: string\n description: |\n Certificate ID from the eBay Developer Program.\n Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted value is not kept.\n ruName:\n type: string\n description: eBay RuName (Redirect URL Name) for OAuth flows\n\nAmazonMWS:\n type: object\n description: |\n Amazon MWS-specific iClient config.\n Note: Amazon MWS is being succeeded by the Selling Partner API (SP-API).\n properties:\n accessKeyId:\n type: string\n description: AWS Access Key ID for Amazon MWS API authentication\n secretKey:\n type: string\n description: |\n AWS Secret Access Key. Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted key is not kept.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1140,"content_sha256":"6b2b226b42def68f40a05c6ed15bc7c632a2549c7f9890ed9ab40fd161bc6634"},{"filename":"references/iclient-schemas/netsuite.yml","content":"NetSuite:\n type: object\n description: |\n NetSuite-specific iClient config for Token-Based Authentication (TBA):\n a NetSuite integration record's consumer key and secret.\n A connection with authType \"token-auto\" needs no iClient: Celigo\n supplies the OAuth client.\n properties:\n consumerKey:\n type: string\n description: |\n NetSuite consumer key from the integration record.\n Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted key is not kept.\n consumerSecret:\n type: string\n description: |\n NetSuite consumer secret from the integration record.\n Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted secret is not kept.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":797,"content_sha256":"84341c02d3eb3add580ca0cc355550c5b7dd38cd233f4457ef2935faadbd8331"},{"filename":"references/iclient-schemas/oauth2.yml","content":"OAuth2:\n type: object\n description: OAuth 2.0 configuration for iClients\n properties:\n clientId:\n type: string\n description: OAuth2 client ID from your app registration. Public value included in auth requests.\n clientSecret:\n type: string\n description: |\n OAuth2 client secret. Stored encrypted; API responses return \"******\".\n Re-send the \"******\" mask on update to keep it. Never omit it: an update\n that sends oauth2 without clientSecret fails with 422 missing_required_field.\n scope:\n type: string\n description: Space-delimited scope string (e.g., \"read write openid\")\n scopeDelimiter:\n type: string\n description: |\n Character used to separate scopes. Default is space per OAuth2 spec.\n Set only if the provider uses a non-standard delimiter (e.g., comma).\n redirectUri:\n type: string\n description: |\n OAuth2 redirect/callback URI. Must be registered with the auth server.\n Use HTTPS. Must match exactly what the provider expects.\n clientCredentialsLocation:\n type: string\n enum: [basicauthheader, body]\n description: |\n Where client credentials are sent in the token request:\n - basicauthheader: Base64-encoded in Authorization header (default, preferred)\n - body: As form parameters client_id/client_secret in POST body\n grantType:\n type: string\n enum: [authorizecode, password, clientcredentials]\n description: |\n OAuth2 grant type:\n - authorizecode: Standard web flow with user consent (most common)\n - clientcredentials: Machine-to-machine, no user interaction\n - password: Legacy; user provides credentials directly (discouraged)\n validDomainNames:\n type: array\n items:\n type: string\n description: |\n Registrable domains (the host minus its subdomains) of the OAuth URLs\n (auth, token, revoke), each once. A full hostname never matches: the\n connection test fails with [invalid_domain] and no request is sent.\n Example: [\"microsoftonline.com\"] for login.microsoftonline.com;\n [\"example.co.uk\"] for auth.example.co.uk\n failPath:\n type: string\n description: |\n Path to auth error field in HTTP response body.\n Set only if the API uses a body field (not just status code) to indicate auth errors.\n Example: \"errorMessage\", \"errors.0.message\"\n failValues:\n type: array\n items:\n type: string\n description: |\n Values at failPath that indicate auth failure.\n Example: [\"access_denied\", \"invalid_grant\"]\n failStatusCode:\n type: number\n description: |\n HTTP status code indicating auth error. Set only if the provider\n uses something other than 401 (e.g., 400 with body error field).\n accessTokenLocation:\n type: string\n enum: [url, header, body]\n description: |\n Where the access token is placed in API requests:\n - header: Authorization header (default, preferred)\n - url: Query parameter\n - body: POST body parameter\n accessTokenHeaderName:\n type: string\n description: Header name for access token. Default \"Authorization\".\n accessTokenPath:\n type: string\n description: JSON path to extract access token from token endpoint response\n accessTokenParamName:\n type: string\n description: Parameter name when access token is passed as query/body param\n refreshTokenPath:\n type: string\n description: JSON path to extract refresh token from token endpoint response\n useIClientFields:\n type: boolean\n description: Use iClient-specific fields instead of standard OAuth2 fields (legacy)\n pkceCodeChallengeMethod:\n type: string\n enum: [plain, s256]\n nullable: true\n description: |\n PKCE code challenge method (RFC 7636).\n s256 is recommended. plain only if required by the provider.\n scheme:\n type: string\n description: Authorization scheme identifier for OAuth2 flow\n auth:\n type: object\n description: Authorization endpoint configuration\n properties:\n uri:\n type: string\n description: |\n Authorization endpoint URL. Required for authorization code flow.\n Example: \"https://accounts.example.com/oauth2/authorize\"\n token:\n type: object\n description: Token endpoint configuration\n properties:\n method:\n type: string\n enum: [GET, POST]\n description: HTTP method for token request. POST is standard and recommended.\n uri:\n type: string\n description: |\n Token endpoint URL. Required for code, credentials, and password flows.\n Example: \"https://auth.example.com/oauth2/token\"\n body:\n type: string\n description: |\n Additional body content for the token request.\n Format: application/x-www-form-urlencoded key=value pairs.\n headers:\n type: string\n nullable: true\n description: Additional HTTP headers for the token request\n refresh:\n type: object\n description: Token refresh endpoint configuration\n properties:\n uri:\n type: string\n description: Refresh token endpoint URL\n method:\n type: string\n enum: [GET, POST]\n description: HTTP method for refresh request. POST is standard.\n body:\n type: string\n description: Body parameters for the refresh request\n headers:\n type: string\n nullable: true\n description: Additional HTTP headers for the refresh request\n revoke:\n type: object\n description: Token revocation endpoint configuration (RFC 7009)\n properties:\n uri:\n type: string\n description: Revocation endpoint URL\n body:\n type: string\n description: |\n Body for revocation request. Typically includes:\n token=\u003ctoken>&token_type_hint=refresh_token\n headers:\n type: string\n nullable: true\n description: Additional HTTP headers for the revocation request\n username:\n type: string\n description: Username for password grant flow\n password:\n type: string\n description: |\n Password for password grant flow. Stored encrypted;\n API responses return \"******\". Re-send the mask on update to keep it;\n an omitted password is not kept.\n unencrypted:\n type: object\n description: |\n Non-sensitive fields accessible via {{{iClient.fieldName}}} in resources.\n Example: {\"email\": \"[email protected]\", \"accountId\": \"12345\", \"role\": \"admin\"}\n encrypted:\n type: object\n description: |\n Sensitive fields stored with AES-256 encryption, accessible via {{{iClient.fieldName}}}.\n API responses return \"******\" for set values.\n Example: {\"password\": \"\u003cpassword>\", \"token\": \"\u003capi-token>\"}\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":7084,"content_sha256":"a3671e5c52433688751c4161ef9e1cb839b9c25f6f32e4219936e54dc69eb4bc"},{"filename":"references/iclient-schemas/request.yml","content":"Request:\n type: object\n description: |-\n iClient configuration. The shape varies by `provider` — each provider\n requires its own credential sub-object (`oauth2`, `netsuite`,\n `salesforce`, `ebay`, `amazonmws`, `azureserviceprincipal`,\n `googleserviceaccount`, `awsIam`).\n For `custom_oauth2`, credentials go in the `oauth2` sub-object.\n Secrets (`clientSecret`, `privateKey`, and so on) come back masked\n as `\"******\"`. Re-send that mask on update to keep the stored\n secret; omitting it does not. Two providers differ. A Google\n service account: `serviceAccountJSON` is not returned, and every\n update must send the full key — the mask or an omission fails with\n 422 `invalid_json_key`. An Azure service principal: the stored\n `clientSecret` or `certificate` is kept when its field is omitted\n on update, and only a new value replaces it (`certificate` is never\n returned, not even masked).\n required:\n - provider\n allOf:\n - $ref: \"./base.yml#/IClientBase\"\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1014,"content_sha256":"14c7c92ccb4defba5a763e80a4498cbc29766bc2a8dd04e812db143b895e37fc"},{"filename":"references/iclient-schemas/response.yml","content":"iClient:\n type: object\n required:\n - _id\n - provider\n - lastModified\n description: |-\n iClient object as returned by the API. Includes all request fields\n plus server-managed metadata. `name` is optional on create and is\n omitted from GET responses when the iClient was created without\n one (the create response echoes it as `null`).\n allOf:\n - $ref: './base.yml#/IClientBase'\n - $ref: '../common-schemas/resource-response.yml#/ResourceResponse'\n - $ref: '../common-schemas/ia-resource-response.yml#/IAResourceResponse'\n\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":555,"content_sha256":"df9b080531c1f70b4ea6d2439c460f2b84a2fa2b71d8e9f929d8d94292d7079f"},{"filename":"references/iclient-schemas/salesforce.yml","content":"Salesforce:\n type: object\n description: |\n Salesforce-specific iClient config for custom Connected App OAuth.\n Used when the connection's salesforce._iClientId points at it; a\n connection that omits salesforce._iClientId uses Celigo's Connected App.\n properties:\n clientId:\n type: string\n description: Consumer key from the Salesforce Connected App\n clientSecret:\n type: string\n description: |\n Consumer secret from the Salesforce Connected App.\n Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted secret is not kept.\n apiToken:\n type: string\n description: |\n Salesforce API token. Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted token is not kept.\n privateKey:\n type: string\n description: |\n Private key for JWT bearer token flow (PEM format).\n Stored encrypted; API responses return \"******\".\n Re-send the mask on update to keep it; an omitted key is not kept.\n publicKey:\n type: string\n description: Public key for API signature verification (PEM format)\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1192,"content_sha256":"09b7b6a3b9ebd6d814a291a3803f7c8ac586d2b093293084d13f09f81e0661d7"},{"filename":"references/iclients.md","content":"# iClients (Shared Credential Stores)\n\nAn iClient is a **reusable credential store** that can be shared across multiple connections. Most hold an OAuth app registration -- the client ID, client secret, scopes, and provider-specific OAuth configuration. Three hold a cloud identity instead: `awsIam` (an AWS IAM role Celigo assumes), `azureserviceprincipal` (a Microsoft Entra service principal), and `googleserviceaccount` (a Google Cloud service-account key). Instead of embedding app credentials directly in each connection, you create one iClient and reference it.\n\n## When Do You Need an iClient?\n\n| Scenario | iClient needed? |\n|---|---|\n| HTTP connection with pre-built connector that has a global iClient | Use the **global iClient** the connector's form names (or applies at authorization). No custom iClient needed. |\n| HTTP connection with OAuth2 using a custom app registration | Yes -- create a **custom iClient** with your clientId/clientSecret, reference via `http._iClientId` (the connection itself doesn't keep a client id or secret) |\n| Salesforce connection through the customer's own Connected App | Yes -- a `salesforce` iClient with the app's credentials, referenced by `salesforce._iClientId` (omit it to use Celigo's Connected App) |\n| NetSuite connection with `authType: \"token-auto\"` | No -- Celigo supplies the OAuth client; the connection needs only `netsuite.account` |\n| HTTP connection with pre-built connector (no global iClient) | Maybe -- check if the connector's auth requires one |\n| HTTP connection with token auth (no OAuth) | No -- credentials go directly on the connection |\n| Amazon S3, Redshift, or an AWS HTTP connector authenticating with an IAM role | Yes -- an `awsIam` iClient (`s3.authType: \"awsIam\"`, `rdbms.redshift.authType: \"awsIam\"`, or `http.auth.type: \"awsiam\"`) |\n| SQL Server (cloud), Azure Synapse, or ADLS Gen2 with a service principal | Yes -- an `azureserviceprincipal` iClient (`rdbms.mssql.authType: \"azure-service-principal\"` on the databases) |\n| Google Cloud Storage with a service-account key | Yes -- a `googleserviceaccount` iClient |\n| Other database, FTP, or non-OAuth connections | No |\n\nThe rule of thumb: **if a global iClient exists for the connector, use it. If the connection uses OAuth and you're bringing your own app registration, or authenticates as a cloud identity, create an iClient.**\n\n## How iClients Relate to Connections\n\n```\n┌──────────────┐ _iClientId ┌──────────────┐\n│ Connection │ ──────────────────────► │ iClient │\n│ (HTTP/SF/NS) │ │ (OAuth app) │\n└──────────────┘ └──────────────┘\n │\n stores clientId, clientSecret,\n scopes, token/refresh/revoke\n endpoints, provider config\n```\n\n- **Connection** owns the concurrency, health monitoring, debug logging, and runtime config\n- **iClient** owns the app registration (or cloud identity) credentials and flow configuration\n- Multiple connections can share one iClient (e.g., multiple connections to the same OAuth app)\n\n### Reference fields on connections\n\n- **HTTP connections:** `http._iClientId` -- when `http.auth.type` is `oauth` and `oauth.useIClientFields: true`, or `awsiam` (an `awsIam` iClient)\n- **Salesforce connections:** `salesforce._iClientId` -- the customer's own Connected App; omit it to use Celigo's\n- **MCP connections:** `mcp.http._iClientId` -- required when `mcp.http.auth.type` is `oauth` (MCP connections accept `token`, `oauth`, or `custom` auth)\n- **S3 and RDBMS connections:** `s3._iClientId` or `rdbms._iClientId` -- an IAM role (S3, Redshift) or a service principal (SQL Server, Azure Synapse)\n- **NetSuite connections:** a `token-auto` connection needs none -- Celigo supplies the OAuth client\n\n## How to Build an iClient\n\n### 1. Determine the provider\n\nThe `provider` field selects which auth configuration is used:\n\n| System | Provider value |\n|---|---|\n| Google APIs | `google` |\n| Salesforce | `salesforce` |\n| Azure AD / Microsoft | `azureoauth` |\n| NetSuite (TBA) | `netsuite` |\n| Shopify | `shopify` |\n| Any custom OAuth2 API | `custom_oauth2` |\n| eBay | `ebay` or `ebay-xml` |\n| AWS IAM role (S3, Redshift, AWS HTTP connectors) | `awsIam` |\n| Microsoft Entra service principal (SQL Server cloud, Azure Synapse, ADLS Gen2) | `azureserviceprincipal` |\n| Google Cloud service account (Google Cloud Storage) | `googleserviceaccount` |\n\nSee [request.yml](iclient-schemas/request.yml) for the full provider enum.\n\n### 2. Build the iClient\n\nUse the schema for the matching provider. All schemas are in [references/iclient-schemas/](iclient-schemas/):\n\n| Provider | Schema | Key fields |\n|---|---|---|\n| Base fields (all) | [request.yml](iclient-schemas/request.yml) | `provider`, `name`, `formType` |\n| Response shape | [response.yml](iclient-schemas/response.yml) | `_id`, `_userId`, timestamps |\n| `custom_oauth2`, `google`, `azureoauth`, `shopify`, etc. | [oauth2.yml](iclient-schemas/oauth2.yml) | `clientId`, `clientSecret`, `scope`, `grantType`, token/refresh/revoke endpoints, PKCE |\n| `netsuite` | [netsuite.yml](iclient-schemas/netsuite.yml) | `consumerKey`, `consumerSecret` |\n| `salesforce` | [salesforce.yml](iclient-schemas/salesforce.yml) | `clientId`, `clientSecret`, optional `privateKey` for JWT bearer |\n| `ebay`, `ebay-xml` | [ebay.yml](iclient-schemas/ebay.yml) | `appId`, `devId`, `certId` |\n| `amazonmws` | [ebay.yml](iclient-schemas/ebay.yml) | `accessKeyId`, `secretKey` |\n| `awsIam`, `azureserviceprincipal`, `googleserviceaccount` | [base.yml](iclient-schemas/base.yml) | `roleArn` and `externalId`; `tenantId`, `clientId`, and a `clientSecret` or `certificate`; `serviceAccountJSON` |\n\nEvery iClient needs at minimum: `provider` and the matching provider-specific config block (`oauth2{}`, `netsuite{}`, `salesforce{}`, etc.).\n\n### 3. Reference from the connection\n\nAfter creating the iClient, set the `_iClientId` on the connection (`http._iClientId`, `salesforce._iClientId`, `mcp.http._iClientId`, `s3._iClientId`, `rdbms._iClientId`).\n\nFor an authorization-code connection, then authorize the connection in a browser; client-credentials and cloud-identity connections need no authorization step.\n\n## custom_oauth2 and JWT-Based Auth\n\n### `custom_oauth2` -- the generic OAuth2 escape hatch\n\nPick a **named `provider`** whenever one matches the system -- it carries provider-aware defaults and the correct sub-config shape. Reach for **`custom_oauth2`** only for OAuth2 APIs with no named provider; because nothing is preset, you supply the flow details yourself:\n\n- `clientId` / `clientSecret` -- the registered app's credentials\n- `scope` (+ `scopeDelimiter`) and `redirectUri` (must match the callback registered with the provider **exactly**)\n- `grantType` -- `authorizecode`, `clientcredentials`, or `password` (exact enum values)\n- token / refresh / revoke endpoints, plus `clientCredentialsLocation` (send client credentials in a basic-auth header vs the request body)\n- PKCE settings where the provider requires them\n- `validDomainNames` -- the registrable domain of each OAuth URL (token, authorization, revoke): `microsoftonline.com` for `https://login.microsoftonline.com/\u003ctenant>/oauth2/v2.0/token`, `example.co.uk` for `auth.example.co.uk`. A hostname never matches: the connection test fails with `[invalid_domain] … validDomainNames` and nothing is sent, and the authorization URL isn't issued either. Adding the API host's registrable domain is harmless.\n- `accessTokenPath` / `refreshTokenPath` -- where the token endpoint's JSON response carries each token (`access_token`, `data.refresh_token`), not endpoint URLs; those go in `token.uri` and `refresh.uri`. `refreshTokenPath` is read on every refresh too: a refresh token found there (at `refresh_token` when unset) replaces the stored one, so a provider that rotates refresh tokens and nests the new one needs it, or the connection keeps sending the token it already used\n\nSee [oauth2.yml](iclient-schemas/oauth2.yml) for the full field set.\n\n### JWT-based auth\n\nSome providers require a **JWT assertion** as part of the token request. Set `enableJWT: true` and populate the `jwt` block on the iClient; for Salesforce JWT bearer, supply the `privateKey` (see [salesforce.yml](iclient-schemas/salesforce.yml)). Handlebars templates reference the signed token via `{{{iClient.jwt.token}}}`. The `clientSecret` and private key are credentials -- the [Credential Discipline & Runtime Behavior](../SKILL.md#credential-discipline--runtime-behavior) rules apply: never paste them in chat.\n\n## One iClient, Many Connections\n\nAn OAuth iClient is the **app registration, not an identity**. It holds the app's `clientId` / `clientSecret`, while the per-user access and refresh tokens produced by actually running the OAuth flow live on the **connection**, not the iClient. That's why the default is **one iClient, many connections** -- register the app once, store it as an iClient, and point every connection that should authenticate as that app at it via `_iClientId`. Ten Salesforce connections for ten different orgs can all share one iClient: same app, ten distinct authenticated identities.\n\nMinting a separate iClient per connection duplicates the same `clientId` / `clientSecret` and multiplies rotation work. Reach for **distinct iClients** only when connections genuinely need *different registered apps* -- different developer accounts, different scope grants, separate rate-limit pools, or a hard separation between environments where each has its own provider-side app.\n\n## Update an iClient in Place vs Create a New One\n\n- **Secret rotated** (the provider reissued it, or it leaked) -> **update the existing iClient in place**. Every connection authenticating through it picks up the new secret with no retargeting.\n- **The app itself changed** (a different registered app, a different developer account, a move to a new client ID) -> create a **new iClient**. The old one stays usable for connections still on the old app; connections migrate to the new one as needed.\n\nSmell test (mirrors connections): renewing the same app's credentials -> update in place; switching to a different app -> new iClient.\n\n## iClient Operations\n\niClients support list, read, create, update (a full-document replace), and delete. The only targeted single-field change is `oauth2.failPath`; every other change is a full-document update.\n\n**An iClient update keeps secrets the same way a connection update does.** Send every secret field back exactly as the read returned it: the masked `\"******\"` keeps the stored secret. Never leave a secret out to keep it -- depending on the provider, the update is refused (an `oauth2` block without `clientSecret` gets 422 `missing_required_field`) or the secret isn't preserved. Two providers differ:\n\n- **Google service account:** the key is never returned, and every update must carry the full JSON key (the mask or an omission fails with 422 `invalid_json_key`), so that change is the user's to make in the Celigo UI.\n- **Azure service principal:** an omitted `clientSecret` or `certificate` is kept (the certificate is never returned, not even masked).\n\nApart from a Google service account, changing an iClient's scopes, endpoints, or `validDomainNames` needs no secret from the user. A connection treats the mask the same way -- see [Credential Discipline](../SKILL.md#never-accept-or-echo-real-credentials-in-chat).\n\n**Deleting an iClient** is refused with 422 (`this document is referenced by Connection : \u003cid>`) while any connection points at it -- including a deleted connection still in the recycle bin, which the iClient's dependency list no longer shows. Re-point the connection, or purge the binned one first. The delete is permanent: iClients don't go to the recycle bin.\n\n## iClient Gotchas\n\n1. **`_httpConnectorId` is immutable.** Once an iClient is linked to an HTTP connector, it cannot be changed. Create a new iClient if you need a different connector.\n2. **`provider` determines valid fields.** Setting `provider: \"netsuite\"` means the `netsuite` block is used; `provider: \"custom_oauth2\"` means the `oauth2` block. Mismatching provider and config block silently ignores the wrong block.\n3. **Handlebars references use `{{{iClient.fieldName}}}`** to access values stored in `encrypted` or `unencrypted` objects. For JWT: `{{{iClient.jwt.token}}}`.\n4. **`validDomainNames` holds registrable domains, never hostnames.** List the registrable domain of each token, authorization, and revoke URL (`microsoftonline.com`, not `login.microsoftonline.com`). A connection test or an authorization that fails with `[invalid_domain]` (\"The domain of request url should be present in iClient.oauth2.validDomainNames\") is fixed here, never on the connection.\n5. **A referenced iClient can't be deleted, and a delete is permanent.** Every connection that points at it blocks the delete (422), a deleted one still in the recycle bin included -- see [iClient Operations](#iclient-operations). A deleted iClient can't be restored.\n6. **Editing a shared iClient's credentials affects every referencing connection.** Because one iClient backs many connections, rotating its `clientSecret` re-points OAuth for all of them at once. Confirm which connections depend on the iClient before changing it.\n7. **The mask keeps an iClient's secret; leaving it out doesn't.** Connections work the same way. On an update, send every secret field back exactly as read, the `\"******\"` included -- see [iClient Operations](#iclient-operations) for the two providers that differ.\n8. **A 404 on a connector connection's iClient isn't a deleted iClient.** Celigo's published (global) iClient lives in Celigo's account, so reading it from the customer's account returns 404 `invalid_ref`. Don't replace it with a custom iClient unless the customer needs their own app.\n9. **An `awsIam` iClient serves one connection family.** The role in `awsIam.roleArn` must be named for the family that assumes it -- `celigo-file-adaptor-` (S3), `celigo-data-warehouse-adaptor-` (Redshift), `celigo-http-adaptor-` (AWS HTTP connectors) -- so S3 and Redshift each need their own iClient; the connection save fails with 422 `invalid_field_value` on a wrong prefix, and with 422 `missing_required_field` while the iClient has no `roleArn`. `awsIam.externalId` is fixed at creation (an update keeps the stored value) and must match the `sts:ExternalId` condition in the role's trust policy. Leave access keys, or a database user and password, off a connection that authenticates as an IAM role or a service principal: the API stores them unused instead of refusing them. The connection forms offer a certificate service principal on SQL Server only; Azure Synapse and ADLS Gen2 take client-secret ones.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":15080,"content_sha256":"71d415e01856634f3e0eb6db355002044cd1ea6336eacef04130561864cefad8"},{"filename":"references/mcp.md","content":"# Configuring Connections with the Celigo MCP Tools\n\nThe tool calls for each section of the configuring-connections skill, for agents connected to the Celigo Platform MCP server. Section and step names match [SKILL.md](../SKILL.md).\n\n## Ids\n\n- `delete_resource` takes a plural `resourceType` -- `\"connections\"`, `\"iclients\"` -- and `list_audit_log_entries` a singular one (`\"connection\"`, `\"iclient\"`).\n- Exports and imports carry a connection's `_id` as `_connectionId`. A connection carries its iClient's `_id` as `http._iClientId`, `salesforce._iClientId`, `mcp.http._iClientId`, `s3._iClientId`, `rdbms._iClientId`, or `netsuite._iClientId`, and its HTTP connector's `_id` as `http._httpConnectorId`.\n- `list_connections` has no name or integration filter, and the API answers 500 to `include` on connections -- list them whole and match client-side on connector identity (`http._httpConnectorId`, `http._httpConnectorApiId`, legacy `assistant`; for other types the `type` and its target), not on `name`.\n\n## Writes\n\n**No tool patches a connection.** A whitelisted field -- `name`, the debug window, the concurrency settings, borrowing, auto-recover, and `endUserProvidedFields` (SKILL.md, Connection Operations) -- goes through the UI or the CLI's `connections set`; never fall back to a full update for one. `upsert_connection` with an `_id` is a full PUT: it keeps each stored secret whose `******` mask goes back exactly as read, and clears a secret it leaves out (a static-token connection without its token is refused with 422 instead). A credential or auth-type change needs the new secret, so it's the user's to make in the UI, where re-entering the credential or re-authorizing is part of the save (SKILL.md, Credential Discipline).\n\n**Masked credentials.** `list_connections` returns stored credentials as `******`. Sent back unchanged, a mask keeps its stored secret, and `upsert_connection` refuses a body carrying one unless you pass `force: true`. Pass it only with masks this connection's own read returned. The tool's description and error message may say the mask wipes the secret and suggest leaving the masked fields out; leaving them out is what clears them. **Rotating a secret** is the user's job in the Celigo UI: a credential pasted into chat is compromised (see Credential Discipline), so you never write one you were given.\n\n**A full update** (a base URI, an endpoint, a header): read the connection with `list_connections` and the `_id`, edit it, then send `upsert_connection` the `_id`, the complete document with every `******` left as read, and `force: true`. PUT replaces the whole document and erases omitted fields -- a partial `http` object wipes the auth configuration. Leave out the server-managed and read-only fields a GET returns (`_id`, `lastModified`, `createdAt`, `offline`, `sandbox`, `queues`, `connectionRole`).\n\n```\nlist_connections({ _id: \"\u003cconnectionId>\" })\nupsert_connection({ _id: \"\u003cconnectionId>\", force: true, body: \u003cthe complete edited document, every ****** left exactly as read> })\n```\n\n**iClients follow the same mask rule.** The iClient API keeps a secret sent back as the exact `******` mask, so `upsert_iclient` with an `_id` takes the complete document with every secret field as read (it needs no `force`). Never drop a secret to keep it, whatever the tool's description says: an `oauth2` block without `clientSecret` is refused with 422 `missing_required_field`, and only an Azure service principal keeps an omitted `clientSecret` or `certificate`. A Google service account iClient needs its full JSON key on every update, so that change is the user's, in the UI (SKILL.md, iClient Operations).\n\n**Schema first.** Before a create or update, `get_schema({ target: \"resource\", name: \"connection/\u003ctype>\" })` returns that adaptor's JSON schema. `\u003ctype>` is the connection `type` (`http`, `netsuite`, `salesforce`, `rdbms`, `jdbc`, `mongodb`, `dynamodb`, `ftp`, `s3`, `filesystem`, `as2`, `van`, `mcp`, `wrapper`, `rest`) or a shared block (`oauth`, `jwt`, `ssl`, `pgp`); `name: \"connection\"` alone lists them in `availableSubSchemas`. iClients have one schema: `get_schema({ target: \"resource\", name: \"iclient\" })`.\n\n## 3. Check for existing connections\n\n```\nlist_connections({}) // every connection -- match connector identity client-side, not the name\nlist_connections({ limit: 100 }) // one page; pass nextCursor back as cursor\nlist_connections({ _id: \"\u003cconnectionId>\" }) // offline, queues, the auth shape (credentials masked)\nlist_marketplace({}) // published templates, most-installed first\nlist_marketplace({ _id: \"\u003ctemplateId>\" }) // a template's blueprint: its objects[] entries with model \"Connection\"\n```\n\n**What uses a connection.** No read-only tool lists a connection's dependents. List exports and imports and match their `_connectionId` client-side, and connections on their `_borrowConcurrencyFromConnectionId`. `delete_resource` scans for dependents and returns them in `warnings`, but only as part of a delete attempt -- never use it as a probe: a connection nothing uses is deleted on the spot.\n\n**Offline and orphaned connections.** There is no account lint: filter the connection list on `offline: true`, then match those connections against the exports and imports of enabled flows.\n\n## 4. Check for a pre-built connector and global iClient\n\n```\nget_schema({ target: \"connector\", name: \"\u003capplication-name>\" }) // case-insensitive name match over the catalog: the connector, or the candidates\nget_schema({ target: \"connector\", name: \"\u003cconnectorId>\" }) // the full connector, including its connection form\nget_schema({ target: \"connector_openapi\", name: \"\u003cconnectorId>\" }) // its OpenAPI fragment\n```\n\nThe connector's connection form is `supportedBy.connection` (a connector grouped into APIs can carry one per `apis[]` entry). Its `preConfiguredFields` are what a connection created from the connector gets -- the entry whose `path` is `http._iClientId`, when there is one, names the global iClient in `values` -- and `fieldsUserMustSet` lists what the user must supply (credentials, settings, scopes). A connection that authorizes through the global iClient can show `http._iClientId` empty at rest, so find the global iClient in the form, not on another connection.\n\n## 5. Choose the type, auth method, and build\n\n```\nget_schema({ target: \"resource\", name: \"connection/http\" })\nupsert_connection({ body: { name: \"Shopify - my-store\", type: \"http\", http: { ... } } })\n```\n\nThere is no connector scaffold over MCP: build the body from the connector's `preConfiguredFields` (step 4) and set `http._httpConnectorId` and `http._httpConnectorVersionId` yourself, plus `http._httpConnectorApiId` for a connector with more than one API. A create takes no `_id`. Read the connection back with `list_connections({ _id })`: a connector id that doesn't resolve is dropped rather than refused (SKILL.md, step 4). A *Celigo APIs* connection also needs `accessScope`, which its form doesn't list.\n\nTo create at a given concurrency, put the level in `\u003ctype>.targetConcurrencyLevel`: a create gets auto-recover unless the body sends `autoRecoverRateLimitErrors: false`, and with it on the body's `\u003ctype>.concurrencyLevel` is replaced by the target, or by the adaptor default without one (HTTP 25, so a body asking for 10 can run at 25). `list_connections({ _id })` shows what was stored (SKILL.md, gotcha 11).\n\n## 6. Test the connection\n\nNo MCP tool pings a connection or runs its OAuth authorization -- see Not Available over MCP. After the user authorizes, `list_connections({ _id })` shows `needsAuthorization: false` (a connection never authorized has no such key). `offline` comes only from the platform's connection test, which a save runs when the connection has one -- for HTTP, only with a ping configured -- so read it again a few seconds after a save, and expect no `offline` key at all on an HTTP connection without a ping.\n\nOn native adaptors (NetSuite, Salesforce, RDBMS, ...), `get_schema({ target: \"connector\", name: \"\u003cconnectionId>\" })` returns the connected application's native metadata (record types, fields, picklists) -- the discovery step before building an export.\n\n## Connection Operations\n\n```\nlist_connections({})\nlist_connections({ _id: \"\u003cconnectionId>\" })\nupsert_connection({ body: { ... } }) // create\nupsert_connection({ _id: \"\u003cconnectionId>\", body: { ... } }) // the complete document, only on a connection nothing uses yet -- see Writes\ndelete_resource({ resourceType: \"connections\", _id: \"\u003cconnectionId>\" }) // refused (422) while exports, imports, or borrowers still use it\n```\n\n`delete_resource` on a connection that exports or imports (and so their flows) or a borrowing connection still use is refused with 422 naming each one (SKILL.md, Connection Operations). One nothing uses is deleted to the recycle bin for 30 days, and no MCP tool restores or purges it -- the UI, or the CLI's `recycle-bin`. Confirm the target with the user first. An integration's registered connections are its `_registeredConnectionIds` (`list_integrations({ _id })`); no MCP tool registers or deregisters one.\n\n## Credential Discipline & Runtime Behavior\n\n### Online / offline\n\n`list_connections({ _id })` -- `offline: true` means the connection is offline and skipped during flow execution. Fixing it is a change to an existing connection, so the user makes it in the UI (or with the CLI) -- see Writes.\n\n### Connections as concurrency queues\n\n```\nlist_connections({ _id: \"\u003cconnectionId>\" }) // queues[].size -- always present on one connection\nlist_connections({ fetchQueueSize: true }) // every connection's queues in one call\n```\n\nChanging the level -- `\u003ctype>.concurrencyLevel`, or `\u003ctype>.targetConcurrencyLevel` while `autoRecoverRateLimitErrors` is true -- is a targeted change no MCP tool makes: the user makes it in the UI, or use the CLI (Writes).\n\n### Auto-recover rate-limit errors\n\n```\nlist_audit_log_entries({ resourceType: \"connection\", _resourceId: \"\u003cconnectionId>\" }) // where the concurrency adjustments appear\n```\n\nRe-enabling auto-recover, or turning it off and setting the level in one PATCH, has no MCP tool either -- the UI or the CLI. The records it recovers land in the Resolved errors, which no MCP tool reads.\n\n### Borrowing concurrency\n\nSetting or clearing `_borrowConcurrencyFromConnectionId`, and setting the parent's ceiling to the system's limit (`\u003ctype>.targetConcurrencyLevel` while its `autoRecoverRateLimitErrors` is true, otherwise `\u003ctype>.concurrencyLevel`), are targeted changes with no MCP tool -- the UI or the CLI.\n\n### Wire-level debug logging\n\nNo MCP tool arms a connection's debug window or reads what it captured -- the UI or the CLI.\n\n## iClients\n\n```\nlist_iclients({})\nlist_iclients({ _id: \"\u003ciClientId>\" }) // secrets come back as ******\nget_schema({ target: \"resource\", name: \"iclient\" })\nupsert_iclient({ body: { provider: \"custom_oauth2\", ... } })\nupsert_iclient({ _id: \"\u003ciClientId>\", body: \u003cthe complete edited document, secret fields as read> })\ndelete_resource({ resourceType: \"iclients\", _id: \"\u003ciClientId>\" }) // refused (422) while any connection points at it; otherwise permanent\n```\n\n- An iClient update keeps a secret sent back as the exact `******` mask, so send the secret fields back as read rather than leaving them out: what an omitted secret does depends on the iClient type (see Writes).\n- To see which connections use an iClient before rotating its secret or deleting it, list connections and match `http._iClientId`, `salesforce._iClientId`, `mcp.http._iClientId`, `s3._iClientId`, `rdbms._iClientId`, and `netsuite._iClientId` client-side. A deleted connection still in the recycle bin blocks the delete too but isn't in the list; purging it takes the UI or the CLI's `recycle-bin purge`.\n- On a connector connection, an `http._iClientId` that `list_iclients({ _id })` answers with 404 `invalid_ref` names Celigo's published iClient, which lives in Celigo's account: normal, not a deleted iClient (SKILL.md, step 4).\n- Pointing a connection at an iClient changes its `_iClientId`, which takes a full update of the connection -- so the user makes it in the UI, then authorizes the connection.\n\n## Not Available over MCP\n\n- **Any change to an existing connection.** A targeted change (rename, concurrency, borrowing, auto-recover, the debug window, `endUserProvidedFields`) is the UI or the CLI's `connections set`; anything else is the UI. The one exception is a connection nothing uses yet (Writes).\n- **Connection ping.** Read the connection's `offline` flag instead; ping with the CLI or the UI.\n- **A live check of the NetSuite SuiteApp and bundle** (`netsuite.suiteAppInstalled` is only a snapshot from the last authentication) -- the CLI's `connections suiteapp-status`, or the UI.\n- **A Celigo APIs connection's stored `accessScope`** -- the CLI (`celigo platform get v1/accessScope/connections/\u003cid>`) or the UI.\n- **OAuth authorization.** The user authorizes in the Celigo UI, or with the CLI.\n- **A connection's debug logs** -- arming the window and reading what it captured; the UI or the CLI.\n- **A connection's dependents as a read-only report** -- match `_connectionId` across exports and imports instead.\n- **The account index and lint** (keyword search, offline connections in use, orphaned connections) -- list and filter client-side.\n- **Registering a connection on an integration**, or deregistering it -- the UI, or the CLI's `integrations register-connections` and `integrations deregister-connections`.\n- **Restoring or purging a deleted connection** -- the UI, or the CLI's `recycle-bin restore` and `recycle-bin purge`.\n- **Trading partner connectors** -- the UI, or the CLI's `tp-connectors list`.\n- **Replacing a connection in one call** on a flow, API, Tool, export, or import. Use the CLI or the UI, or `list_\u003ctype>` and `upsert_\u003ctype>` on each export and import that still carries the old `_connectionId` -- same type, and for HTTP the same application (SKILL.md, Connection Operations).\n- **Scaffolding a connection from a connector** -- build the body from the connector's connection form (step 4).\n- **Changing only an iClient's `oauth2.failPath`** -- a full `upsert_iclient`, or the CLI's `iclients set`.\n\nIf a tool misbehaves or lacks something you needed, report it with `submit_feedback`.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":14489,"content_sha256":"74611aba84fb8cfcfd10d57465504c0a44273c2d8c518b87691fe12065907810"},{"filename":"references/schemas/as2.yml","content":"AS2:\n type: object\n description: AS2 (Applicability Statement 2) connection configuration for EDI\n # API behavior:\n # - as2Id and partnerId are writable on POST but silently ignored on PUT (immutable after creation;\n # the connection form disables both fields once the connection exists).\n # - The POST 422s without partnerStationInfo and userStationInfo (and their nested\n # as2URI/signing/encryptionType, enforced in each object's own required array).\n # - Certificate/key requireds are condition-specific: userPrivateKey + userPublicKey are\n # required when partnerStationInfo.signing != NONE OR userStationInfo.encryptionType != NONE;\n # partnerCertificate is required when partnerStationInfo.encryptionType != NONE OR\n # userStationInfo.signing != NONE. The connection form is narrower (it keys both only on the\n # matching encryptionType), so the if/then/else below mirrors the FORM rule per repo convention;\n # the broader API behavior is documented on each field.\n # - 422 field labels misspell paths (`as2.unecrypted`, `X.509 Public Key`); the real stored\n # paths are `unencrypted`/`userPublicKey`. Trust the storage paths.\n required:\n - as2Id\n - partnerId\n - partnerStationInfo\n - userStationInfo\n properties:\n as2Id:\n type: string\n description: |\n AS2 identifier for this station. Trading partners use this as the \"To\"\n identifier when sending documents, and integrator.io uses it as the \"From\"\n identifier when sending documents to partners.\n\n Must be unique across ALL integrator.io users so inbound documents route\n correctly. Set on creation and cannot be changed afterward — a PUT with a\n different value is ignored. Use a distinct identifier per environment\n (e.g. production vs. non-production). If omitted, a unique value is auto-generated.\n examples: [\"acme-prod-as2\"]\n x-celigo-ui-override: >-\n Required by the connection form (as2.as2Id). The form disables the field once the\n connection exists, mirroring that the value is immutable after creation.\n x-celigo-ai-guidance:\n - |-\n IMPORTANT: This value must be unique across ALL integrator.io users to\n ensure inbound documents are routed correctly. It CANNOT be updated after\n creation. Use a different identifier for production vs. sandbox.\n partnerId:\n type: string\n description: |-\n Trading partner's AS2 identifier — the partner's \"From\" identifier on documents they\n send and the \"To\" identifier integrator.io uses when sending to them. Set on creation\n and cannot be changed afterward; a PUT with a different value is ignored.\n examples: [\"partner-edi-01\"]\n x-celigo-ui-override: >-\n Required by the connection form (as2.partnerId). The form disables the field once the\n connection exists, mirroring that the value is immutable after creation.\n _tpConnectorId:\n type: string\n format: objectId\n x-celigo-refModel: tradingpartnerconnectors\n description: Trading partner connector this AS2 connection was provisioned from during partner onboarding. Omit for a standalone AS2 connection.\n examples: [\"66a1b2c3d4e5f60718293a4b\"]\n contentBasedFlowRouter:\n type: object\n description: |-\n Routes inbound documents to different flows based on message content, for connections\n shared across multiple flows. Omit unless a routing script is required.\n properties:\n function:\n type: string\n description: Function in the routing script that returns the target flow.\n examples: [\"routeByDocType\"]\n _scriptId:\n type: string\n format: objectId\n x-celigo-refModel: scripts\n description: Script containing the routing function named in `function`.\n examples: [\"66b2c3d4e5f60718293a4b5c\"]\n partnerStationInfo:\n type: object\n description: |-\n Partner (remote) station configuration, used on the IMPORT side — controls how messages\n are sent TO the trading partner.\n required:\n - as2URI\n - signing\n - encryptionType\n properties:\n as2URI:\n type: string\n format: uri\n description: |-\n Partner's AS2 endpoint that integrator.io posts outbound messages to.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data\n sent to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n examples: [\"https://partner.example.com/as2\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.as2URI).\"\n mdn:\n type: object\n description: Settings for the MDN (Message Disposition Notification) receipt the partner returns for outbound messages.\n required:\n - mdnSigning\n properties:\n mdnURL:\n type: string\n format: uri\n description: |-\n Endpoint the partner posts asynchronous MDNs to. Set only when the partner\n returns MDNs asynchronously rather than on the same connection.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol;\n data sent to an HTTP endpoint is not encrypted and may be intercepted or\n modified in transit.\n examples: [\"https://partner.example.com/as2/mdn\"]\n signatureProtocol:\n type: string\n enum:\n - pkcs7-signature\n x-enumDescriptions:\n pkcs7-signature: PKCS#7 digital signature format for signing MDN responses.\n description: Signature protocol the partner uses on returned MDNs.\n examples: [\"pkcs7-signature\"]\n mdnSigning:\n type: string\n enum:\n - NONE\n - SHA1\n - MD5\n - SHA256\n x-enumDescriptions:\n NONE: Do not verify the MDN signature; accept unsigned MDNs.\n SHA1: Verify the returned MDN signature using the SHA-1 hash algorithm.\n MD5: Verify the returned MDN signature using the MD5 hash algorithm.\n SHA256: Verify the returned MDN signature using the SHA-256 hash algorithm.\n description: Hash algorithm used to verify the signature on MDNs the partner returns. Defaults to NONE when the partner does not sign MDNs.\n examples: [\"SHA256\"]\n x-celigo-ui-override: >-\n Defaulted to NONE by the connection form when MDN verification is off\n (preSave sets as2.partnerStationInfo.mdn.mdnSigning to 'NONE' if empty).\n verifyMDNSignature:\n type: boolean\n description: When true, verifies the signature on MDNs returned by the partner. Requires unencrypted.partnerCertificate.\n auth:\n type: object\n description: |-\n Authentication for posting messages to the partner's AS2 endpoint. Omit (or set\n type to none) when the endpoint is unauthenticated.\n properties:\n type:\n type: string\n enum:\n - basic\n - token\n - none\n x-enumDescriptions:\n basic: HTTP Basic Authentication using a username and password.\n token: Token-based authentication, optionally with automatic token refresh.\n none: No authentication; the partner endpoint is open.\n description: Authentication scheme for the partner endpoint. Set the matching basic or token sub-object for basic or token.\n examples: [\"token\"]\n x-celigo-ui-override: >-\n Required by the connection form (as2.partnerStationInfo.auth.type). The form\n stores 'none' for unauthenticated endpoints; on create it must be set explicitly.\n failStatusCode:\n type: number\n description: HTTP status code in the partner's response that signals an authentication failure, triggering a token refresh or error.\n examples: [401]\n failPath:\n type: string\n description: Path in the partner's JSON response body checked against failValues to detect an authentication failure.\n examples: [\"error.code\"]\n failValues:\n type: array\n items:\n type: string\n description: Values at failPath that indicate an authentication failure. Requires failPath.\n examples: [[\"invalid_token\", \"expired\"]]\n basic:\n type: object\n description: Credentials for basic authentication. Present when type is basic.\n properties:\n username:\n type: string\n description: Username for basic authentication.\n examples: [\"edi_user\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.auth.basic.username) when auth type is basic.\"\n password:\n type: string\n writeOnly: true\n description: Password for basic authentication. Masked as \"******\" in GET responses.\n examples: [\"s3cr3t-p4ss\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.auth.basic.password) when auth type is basic.\"\n token:\n type: object\n description: Token configuration. Present when type is token.\n properties:\n token:\n type: string\n writeOnly: true\n description: Bearer/access token sent with each request to the partner. Masked as \"******\" in GET responses.\n examples: [\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.auth.token.token) when auth type is token.\"\n location:\n type: string\n enum:\n - header\n - url\n - body\n x-enumDescriptions:\n header: Send the token in an HTTP request header.\n url: Send the token as a URL query parameter.\n body: Send the token in the request body.\n description: Where to place the token in the outbound request.\n examples: [\"header\"]\n headerName:\n type: string\n description: Header name carrying the token when location is header. Defaults to Authorization.\n examples: [\"Authorization\"]\n scheme:\n type: string\n enum:\n - bearer\n - mac\n - oauth\n - none\n x-enumDescriptions:\n bearer: Prefix the token with the \"Bearer\" scheme.\n mac: Use the MAC authorization scheme.\n oauth: Use the OAuth scheme.\n none: Send the raw token with no scheme prefix.\n description: Authorization scheme prepended to the token when location is header.\n examples: [\"bearer\"]\n paramName:\n type: string\n description: Query parameter name carrying the token when location is url.\n examples: [\"access_token\"]\n refreshToken:\n type: string\n writeOnly: true\n description: Token used to obtain a new access token when the current one expires. Masked as \"******\" in GET responses.\n examples: [\"1//0eXaMpLeReFrEsHtOkEn\"]\n refreshRelativeURI:\n type: string\n description: Endpoint, relative to the partner's host, called to refresh the token.\n examples: [\"/oauth/token\"]\n refreshMethod:\n type: string\n enum:\n - GET\n - POST\n - PUT\n x-enumDescriptions:\n GET: Refresh the token with an HTTP GET request.\n POST: Refresh the token with an HTTP POST request.\n PUT: Refresh the token with an HTTP PUT request.\n description: HTTP method for the token-refresh request.\n examples: [\"POST\"]\n refreshMediaType:\n type: string\n enum:\n - json\n - urlencoded\n - xml\n x-enumDescriptions:\n json: Send the refresh request body as application/json.\n urlencoded: Send the refresh request body as application/x-www-form-urlencoded.\n xml: Send the refresh request body as application/xml.\n description: Content type of the token-refresh request body.\n examples: [\"json\"]\n refreshBody:\n type: string\n description: Request body sent with the token-refresh request, used when refreshMethod is POST or PUT.\n examples: ['{\"grant_type\":\"refresh_token\"}']\n refreshTokenPath:\n type: string\n description: Path in the refresh response body where the new access token is found.\n examples: [\"access_token\"]\n refreshHeaders:\n type: array\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name to send with the token-refresh request.\n examples: [\"Content-Type\"]\n value:\n type: string\n description: Header value to send with the token-refresh request.\n examples: [\"application/json\"]\n description: Headers sent with the token-refresh request.\n rateLimit:\n type: object\n description: Throttles requests to the partner endpoint when it enforces a non-standard rate limit.\n properties:\n failStatusCode:\n type: number\n description: HTTP status code in the partner's response that indicates rate limiting.\n examples: [429]\n failPath:\n type: string\n description: Path in the partner's JSON response body checked against failValues to detect rate limiting.\n examples: [\"errors.0.code\"]\n failValues:\n type: array\n description: Values at failPath that indicate rate limiting. Requires failPath.\n items:\n type: string\n examples: [[\"TOO_MANY_REQUESTS\"]]\n limit:\n type: number\n minimum: 1\n description: Wait time in milliseconds between requests to the partner endpoint.\n examples: [1000]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.rateLimit.limit) when the non-standard rate limiter is enabled.\"\n SMIMEVersion:\n type: string\n enum:\n - v2\n - v3\n x-enumDescriptions:\n v2: S/MIME version 2 for legacy compatibility.\n v3: S/MIME version 3 with improved security and algorithm support.\n description: S/MIME version applied to outbound messages. Not exposed in the connection form.\n examples: [\"v3\"]\n signing:\n type: string\n enum:\n - NONE\n - SHA1\n - MD5\n - SHA256\n x-enumDescriptions:\n NONE: Send outbound messages unsigned.\n SHA1: Sign outbound messages using the SHA-1 hash algorithm.\n MD5: Sign outbound messages using the MD5 hash algorithm.\n SHA256: Sign outbound messages using the SHA-256 hash algorithm.\n description: Hash algorithm for signing messages sent to the partner. Any value other than NONE requires encrypted.userPrivateKey and unencrypted.userPublicKey.\n examples: [\"SHA256\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.signing).\"\n encryptionType:\n type: string\n enum:\n - NONE\n - DES\n - RC2\n - 3DES\n - AES128\n - AES256\n x-enumDescriptions:\n NONE: Send outbound messages unencrypted.\n DES: Encrypt outbound messages using DES (56-bit key, legacy).\n RC2: Encrypt outbound messages using the RC2 block cipher (legacy, variable key length).\n 3DES: Encrypt outbound messages using Triple DES (168-bit effective key strength).\n AES128: Encrypt outbound messages using AES with a 128-bit key.\n AES256: Encrypt outbound messages using AES with a 256-bit key.\n description: Cipher for encrypting messages sent to the partner. Any value other than NONE requires unencrypted.partnerCertificate.\n examples: [\"AES256\"]\n x-celigo-ui-override: \"Required by the connection form (as2.partnerStationInfo.encryptionType).\"\n encoding:\n type: string\n enum:\n - base64\n - binary\n x-enumDescriptions:\n base64: Base64-encode the message content for safe text transport.\n binary: Send message content as raw binary data.\n description: Content transfer encoding for outbound messages. Shown in the form only when encryptionType is not NONE.\n examples: [\"base64\"]\n signatureEncoding:\n type: string\n enum:\n - base64\n - binary\n x-enumDescriptions:\n base64: Base64-encode the digital signature.\n binary: Send the digital signature as raw binary data.\n description: Encoding applied to the digital signature on outbound messages.\n examples: [\"base64\"]\n userStationInfo:\n type: object\n description: |-\n User (local) station configuration, used on the EXPORT side — controls how inbound\n messages from the partner are processed.\n required:\n - signing\n - encryptionType\n properties:\n mdn:\n type: object\n description: Settings for the MDN receipt this station returns to the partner for inbound messages.\n required:\n - mdnSigning\n properties:\n mdnURL:\n type: string\n # Empty string = asynchronous MDNs not used; anything else must be a URI.\n anyOf:\n - format: uri\n - const: \"\"\n description: |-\n Partner's endpoint this station posts asynchronous MDNs to. Set only when\n the partner requires asynchronous MDNs; stored as an empty string otherwise.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol;\n data sent to an HTTP endpoint is not encrypted and may be intercepted or\n modified in transit.\n examples: [\"https://partner.example.com/as2/async-mdn\"]\n signatureProtocol:\n type: string\n enum:\n - pkcs7-signature\n x-enumDescriptions:\n pkcs7-signature: PKCS#7 digital signature format for signing MDN responses.\n description: Signature protocol applied to MDNs this station returns.\n examples: [\"pkcs7-signature\"]\n mdnSigning:\n type: string\n enum:\n - NONE\n - SHA1\n - MD5\n - SHA256\n x-enumDescriptions:\n NONE: Return MDNs unsigned.\n SHA1: Sign returned MDNs using the SHA-1 hash algorithm.\n MD5: Sign returned MDNs using the MD5 hash algorithm.\n SHA256: Sign returned MDNs using the SHA-256 hash algorithm.\n description: |-\n Hash algorithm used to sign MDNs this station returns to the partner. Signs the MDN\n only — the hash algorithm of its `Received-Content-MIC` follows\n userStationInfo.signing, not this field.\n examples: [\"SHA256\"]\n x-celigo-ui-override: \"Required by the connection form (as2.userStationInfo.mdn.mdnSigning).\"\n mdnEncoding:\n type: string\n enum:\n - base64\n - binary\n x-enumDescriptions:\n base64: Base64-encode the returned MDN content.\n binary: Send the returned MDN as raw binary data.\n description: Encoding applied to MDNs this station returns.\n examples: [\"base64\"]\n signing:\n type: string\n enum:\n - NONE\n - SHA1\n - MD5\n - SHA256\n x-enumDescriptions:\n NONE: Accept inbound messages without verifying their signature; returned MDNs then carry a SHA-1 MIC.\n SHA1: Verify inbound message signatures using the SHA-1 hash algorithm.\n MD5: Verify inbound message signatures using the MD5 hash algorithm.\n SHA256: Verify inbound message signatures using the SHA-256 hash algorithm.\n description: |-\n Hash algorithm for verifying signatures on inbound messages; the same algorithm is used\n for the `Received-Content-MIC` in the MDN returned for each message (NONE falls back to\n SHA-1, and the algorithm the partner requests in `Disposition-Notification-Options` is\n not used). The MIC is computed when a message is received, so a change here applies only\n to messages received afterwards — the partner must resend to get an MDN with the new\n algorithm. Any value other than NONE requires unencrypted.partnerCertificate.\n examples: [\"SHA256\"]\n x-celigo-ui-override: \"Required by the connection form (as2.userStationInfo.signing — labeled Signature verification algorithm).\"\n encryptionType:\n type: string\n enum:\n - NONE\n - DES\n - RC2\n - 3DES\n - AES128\n - AES256\n x-enumDescriptions:\n NONE: Expect inbound messages to be unencrypted.\n DES: Decrypt inbound messages using DES (56-bit key, legacy).\n RC2: Decrypt inbound messages using the RC2 block cipher (legacy).\n 3DES: Decrypt inbound messages using Triple DES (168-bit effective key strength).\n AES128: Decrypt inbound messages using AES with a 128-bit key.\n AES256: Decrypt inbound messages using AES with a 256-bit key.\n description: Cipher for decrypting inbound messages. Any value other than NONE requires encrypted.userPrivateKey and unencrypted.userPublicKey.\n examples: [\"AES256\"]\n x-celigo-ui-override: \"Required by the connection form (as2.userStationInfo.encryptionType — labeled Decryption algorithm).\"\n encoding:\n type: string\n enum:\n - base64\n - binary\n x-enumDescriptions:\n base64: Expect inbound message content in base64 encoding.\n binary: Expect inbound message content as raw binary data.\n description: Content transfer encoding expected on inbound messages. Shown in the form only when encryptionType is not NONE.\n examples: [\"binary\"]\n x-celigo-ui-override: \"Required by the connection form (as2.userStationInfo.encoding) when decryption is enabled.\"\n compressed:\n type: boolean\n description: When true, message content is compressed. Not exposed in the connection form.\n default: false\n encrypted:\n type: object\n description: |-\n Encrypted-at-rest key material for this station's own identity. Supply when this station\n signs outbound messages or decrypts inbound messages; integrator.io injects an\n auto-generated self-signed key otherwise.\n properties:\n userPrivateKey:\n type: string\n writeOnly: true\n description: |-\n PEM-encoded X.509 private key for this station, used to sign outbound messages and\n decrypt inbound ones. Masked as \"******\" in GET responses. Required when\n partnerStationInfo.signing is not NONE or userStationInfo.encryptionType is not NONE.\n x-celigo-ui-override: >-\n Required by the connection form (as2.encrypted.userPrivateKey) when\n userStationInfo.encryptionType is not NONE. The live API additionally requires it when\n partnerStationInfo.signing is not NONE.\n x-celigo-ai-guidance:\n - |-\n Encrypted certificate and key data (stored encrypted at rest).\n Required when signing or encryption is enabled (not NONE).\n Auto-generated self-signed certificates will be injected if not provided.\n unencrypted:\n type: object\n description: |-\n Public certificate material for this station and the partner. integrator.io injects an\n auto-generated self-signed certificate for this station when none is supplied.\n properties:\n userPublicKey:\n type: string\n description: |-\n PEM-encoded X.509 public certificate for this station, paired with\n encrypted.userPrivateKey. Required when partnerStationInfo.signing is not NONE or\n userStationInfo.encryptionType is not NONE.\n x-celigo-ui-override: >-\n Required by the connection form (as2.unencrypted.userPublicKey) when\n userStationInfo.encryptionType is not NONE. The live API additionally requires it when\n partnerStationInfo.signing is not NONE.\n partnerCertificate:\n type: string\n description: |-\n PEM-encoded X.509 certificate for the trading partner, used to encrypt outbound\n messages and verify inbound signatures and MDNs. Required when\n partnerStationInfo.encryptionType is not NONE, userStationInfo.signing is not NONE,\n or partnerStationInfo.mdn.verifyMDNSignature is true.\n x-celigo-ui-override: >-\n Required by the connection form (as2.unencrypted.partnerCertificate) when\n partnerStationInfo.encryptionType is not NONE. The live API additionally requires it\n when userStationInfo.signing is not NONE.\n x-celigo-ai-guidance:\n - |-\n Unencrypted certificate data for identity and partner verification.\n Required when signing or encryption is enabled (not NONE).\n Auto-generated self-signed certificates will be injected if not provided.\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of messages processed concurrently for this connection. The default of 5\n is safe for most partners. Send no more than the account's licensed maximum (25 standard,\n 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |-\n Concurrency ceiling integrator.io scales up to when auto-recovering from rate-limit\n errors. Only applies when autoRecoverRateLimitErrors is true on the connection.\n minimum: 1\n maximum: 50\n examples: [5]\n preventCanonicalization:\n type: boolean\n description: |-\n When true, inbound messages are verified — and the `Received-Content-MIC` in the returned\n MDN is computed — over the content exactly as received, without first normalizing line\n endings to CRLF; the partner's MDN signatures are verified the same way. Enable only when a\n partner reports signature-verification failures or MIC mismatches caused by\n canonicalization.\n default: false\n # Certificate/key requireds are conditional on the signing/encryption settings of BOTH station\n # objects (see the per-field descriptions). The two form rules guard different fields and are\n # independent (both can apply at once), so they can't be expressed as a single if/then/else and\n # an allOf-wrapped if/then is prohibited (renders broken in GitBook — see CLAUDE.md). The\n # conditions are therefore documented on each field via description + x-celigo-ui-override rather\n # than encoded as JSON Schema.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":29127,"content_sha256":"0aa92fb53a1164c3e7125c7a2a98356b5110ea8501bb7f83de3e545d99ee9588"},{"filename":"references/schemas/dynamodb.yml","content":"DynamoDB:\n type: object\n description: |-\n Configuration for Amazon DynamoDB connections. Used when the connection type is \"dynamodb\".\n Authenticates with AWS IAM access keys, which must grant the DynamoDB actions the integration\n uses (GetItem, PutItem, Query, Scan, etc.). The AWS region is resolved per table at request\n time, so no region is stored on the connection.\n required:\n # Only aws (and its accessKeyId/secretAccessKey) are API-enforced — a POST missing any of them\n # returns 422. targetConcurrencyLevel is form-required but NOT API-required (the server defaults\n # it to 5), so it is documented via x-celigo-ui-override on the field rather than added here —\n # adding it would out-strict the API and break the minimal create example.\n - aws\n properties:\n aws:\n type: object\n description: AWS IAM access-key credentials used to sign DynamoDB requests.\n required:\n - accessKeyId\n - secretAccessKey\n properties:\n accessKeyId:\n type: string\n description: |-\n Access key ID of the IAM user or role whose policy grants the required DynamoDB actions.\n examples: [\"AKIA_EXAMPLE_KEY_ID\"]\n secretAccessKey:\n type: string\n description: Secret access key paired with `accessKeyId`. Encrypted at rest and returned masked as `\"******\"`.\n writeOnly: true\n examples: [\"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"]\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of DynamoDB requests this connection runs at once.\n\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ai-guidance:\n - |-\n Maximum number of concurrent DynamoDB operations.\n DynamoDB throughput is governed by table-level read/write capacity units.\n targetConcurrencyLevel:\n type: integer\n description: |-\n Concurrency ceiling for auto-scaling. The system adjusts the active concurrency between 1\n and this value based on rate-limit feedback. Only applied when `autoRecoverRateLimitErrors`\n is enabled on the connection. The same licensed maximum applies as for `concurrencyLevel`.\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ui-override: >-\n Required by the connection form (its targetConcurrencyLevel field is required and defaults to 5).\n The API does not enforce this — a POST that omits it succeeds and the server defaults it to 5.\n Encoded to mirror the form so builders produce complete configurations.\n x-celigo-ai-guidance:\n - >-\n Set aws.accessKeyId and aws.secretAccessKey from an IAM user/role with DynamoDB permissions.\n Both are required: a POST missing either fails with 422 \"Expected field: aws.accessKeyId\n (or aws.secretAccessKey) to be present.\" No AWS region or role ARN is stored — the server\n drops any region/roleARN you send.\n - |-\n ## REQUIRED FIELDS\n - aws.accessKeyId\n - aws.secretAccessKey\n\n The IAM credentials must have appropriate DynamoDB permissions\n (dynamodb:GetItem, dynamodb:PutItem, dynamodb:Query, dynamodb:Scan, etc.).\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":3295,"content_sha256":"ef7fe9a3c3a925456ab516861f9b43f3126e7feb7c100e372c6b2d06e0d65051"},{"filename":"references/schemas/filesystem.yml","content":"Filesystem:\n type: object\n description: |-\n Configuration for filesystem connections. Used when the connection type is \"filesystem\".\n Provides access to directories on a Celigo on-premise Agent's host or mounted network\n drives, so a connection-level `_agentId` is required — cloud-only deployments cannot use\n this type. File-based PGP encryption/decryption is configured through the connection-level\n `pgp` object.\n properties:\n ping:\n type: object\n description: Connection health-check configuration. integrator.io reads this directory to verify the agent can reach the filesystem.\n properties:\n directoryPath:\n type: string\n description: |-\n Absolute directory path the agent checks to confirm filesystem access. Accepts a POSIX path,\n a Windows drive path, or a UNC share. Leave unset to skip the directory check during ping.\n examples: [\"/data/integrations/incoming\", \"C:\\\\Data\\\\Integrations\", \"\\\\\\\\fileserver\\\\Shared\\\\SNFiles\"]\n x-celigo-ai-guidance:\n - |-\n Absolute directory path on the agent's host used for connection health checks.\n The system verifies the directory exists and is accessible.\n Example: \"/data/integrations/incoming\" or \"C:\\\\Data\\\\Integrations\".\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of files processed concurrently. Send no more than `targetConcurrencyLevel` and\n the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 1\n targetConcurrencyLevel:\n type: integer\n description: |-\n Upper bound for auto-scaling. The agent scales concurrency between 1 and this value based on\n throughput, so it also caps `concurrencyLevel`. Send no more than the account's licensed maximum\n (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 1\n x-celigo-ui-override: >-\n Required by the connection form (filesystem.targetConcurrencyLevel is a required select that\n defaults to 1). The API itself defaults it to 1 when omitted; encoded here to mirror the form\n so builders produce complete configurations.\n x-celigo-ai-guidance:\n - |-\n Filesystem connections provide access to the local filesystem on a Celigo on-premise Agent.\n This enables file-based integrations with directories on the agent's host machine or\n mounted network drives.\n\n ## AGENT REQUIREMENT\n A Celigo Agent is REQUIRED for filesystem connections (set _agentId on the parent\n connection object). The agent provides the filesystem access — cloud-only\n deployments cannot use this connection type.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":2805,"content_sha256":"054e04403784fe5d4d7df1a93ef524536e23f1d7e75dac6038ec99c4dde5131e"},{"filename":"references/schemas/ftp.yml","content":"FTP:\n type: object\n description: |-\n Configuration for FTP/SFTP/FTPS file transfer connections. Used when the connection type is \"ftp\".\n The type field selects the transfer protocol, which determines port defaults and available auth methods.\n required:\n - type\n - hostURI\n - username\n properties:\n type:\n type: string\n enum:\n - ftp\n - sftp\n - ftps\n x-enumDescriptions:\n ftp: Standard FTP with no transport encryption (default port 21).\n sftp: SSH-based file transfer with encrypted transport (default port 22); supports SSH key auth via authKey.\n ftps: FTP over TLS/SSL with encrypted transport; port 21 for explicit TLS or 990 for implicit (useImplicitFtps).\n description: |-\n File transfer protocol type. Prefer sftp for security. Use ftps when the\n server requires TLS. Only use ftp for legacy systems without encryption support.\n examples: [\"sftp\"]\n hostURI:\n type: string\n description: |\n FTP server hostname or IP address.\n Do NOT include the protocol prefix (e.g., use \"ftp.example.com\", not \"sftp://ftp.example.com\").\n examples: [\"sftp.example.com\"]\n x-celigo-ai-guidance:\n - |-\n Don't point a connection at this environment's own Celigo file server (its\n `endpoint.hostname`, with a username ending in `@\u003cidentifier>`, the server's own\n `identifier`): a flow reads those files from Celigo Storage directly, and the save\n refuses that pairing with 422 `fileserver_loopback_not_supported`. Another\n environment's file server on the same host, such as a trading partner's, is an\n ordinary connection.\n port:\n type: number\n description: |\n Server port number. When omitted, defaults to the standard port for the\n protocol: 21 for ftp, 22 for sftp, 21 for explicit ftps, and 990 for implicit ftps.\n minimum: 0\n maximum: 65535\n examples: [22]\n username:\n type: string\n description: Username for server authentication.\n examples: [\"ftpuser\"]\n password:\n type: string\n writeOnly: true\n description: |-\n Password for server authentication (encrypted at rest; returned masked as `\"******\"`).\n For sftp, supply either password or authKey (SSH key).\n x-celigo-ui-override: >-\n Required by the connection form: a password for ftp/ftps, or a password or SSH key\n (authKey) for sftp (see the if/then/else rule below). Encoded here to mirror the form\n so builders produce complete, connectable configurations.\n x-celigo-ai-guidance:\n - For ftp/ftps set password; for sftp set password or authKey. The connection cannot authenticate without credentials.\n - For key-only sftp, omit password rather than filling it with a stand-in value — the form's required marker on Password does not apply once authKey is set, and the Help Center notes that servers enforcing a strict authentication order (public key first, then password) are not compatible with supplying both.\n examples: [\"s3cr3t-ftp-passw0rd\"]\n authKey:\n type: string\n description: |-\n SSH private key for SFTP key-based authentication (encrypted at rest; returned masked as `\"******\"`).\n Only used when type is \"sftp\"; can be used alone or alongside a password. Must be an RSA (SSH-2) key\n in PEM format, supplied whole from its BEGIN line to its END line — OpenSSH-format keys (a first\n line that names an OPENSSH PRIVATE KEY), passphrase-protected keys, SSH-1 keys and PuTTY `.ppk` files\n are not supported and must be converted to an unencrypted PEM key first.\n x-celigo-ai-guidance:\n - Never take the key through chat; write a placeholder the user replaces in the connection editor. The matching public key must be in the server's authorized_keys for the username — Celigo holds only the private half.\n - A key whose first line names an OPENSSH PRIVATE KEY, or one that asks for a passphrase, is outside the supported format per the Help Center; `ssh-keygen -p -m PEM -f \u003ckey>` rewrites it as PEM (`-N \"\"` also removes the passphrase).\n writeOnly: true\n usePassiveMode:\n type: boolean\n description: |\n When true, uses passive mode for FTP/FTPS data connections.\n In passive mode, the client initiates both control and data connections,\n which works better through firewalls and NAT. Enable for most scenarios.\n default: true\n enableHostVerification:\n type: boolean\n description: |\n When true, verifies the server's SSH host key (sftp) or TLS certificate (ftps).\n Disable only for development/testing with self-signed certificates.\n userDirectoryIsRoot:\n type: boolean\n description: |\n When true, treats the user's home directory as the root directory.\n All paths are relative to the user's home directory rather than the server root.\n default: false\n useImplicitFtps:\n type: boolean\n description: |\n When true, uses implicit FTPS (TLS connection established immediately on port 990).\n When false, uses explicit FTPS (starts as FTP on port 21, upgrades to TLS via STARTTLS).\n Only applies when type is \"ftps\".\n default: false\n requireSocketReUse:\n type: boolean\n description: |\n When true, requires the data connection to reuse the same TLS session as the control connection.\n Some FTPS servers require this for security. Only applies to FTPS connections.\n default: false\n entryParser:\n type: string\n enum:\n - UNIX\n - UNIX-TRIM\n - VMS\n - WINDOWS\n - OS/2\n - OS/400\n - AS/400\n - MVS\n - UNKNOWN-TYPE\n - NETWARE\n - MACOS-PETER\n x-enumDescriptions:\n UNIX: Standard Unix/Linux directory listing format (most common).\n UNIX-TRIM: Unix format with trimmed whitespace for non-standard servers.\n VMS: OpenVMS directory listing format.\n WINDOWS: Windows FTP server DOS-style directory listing format.\n OS/2: IBM OS/2 directory listing format.\n OS/400: IBM OS/400 directory listing format.\n AS/400: IBM AS/400 (iSeries) directory listing format.\n MVS: IBM mainframe MVS directory listing format.\n UNKNOWN-TYPE: Attempt automatic detection of the listing format.\n NETWARE: Novell NetWare directory listing format.\n MACOS-PETER: macOS Peter's FTP server directory listing format.\n description: |-\n File listing format parser. Controls how directory listings from the server are interpreted.\n Most servers use UNIX format. Only change this if directory listings appear garbled.\n examples: [\"UNIX\"]\n x-uppercase: true\n pgpEncryptKey:\n type: string\n deprecated: true\n description: |\n Deprecated: legacy FTP-scoped PGP public key. Superseded by the connection-level `pgp.publicKey`,\n which the current form writes; retained for the few existing connections still on this path\n (encrypted at rest).\n writeOnly: true\n x-celigo-ai-guidance:\n - |-\n PGP public key for encrypting files before upload (encrypted at rest).\n When set, files are PGP-encrypted before being sent to the server.\n pgpDecryptKey:\n type: string\n deprecated: true\n description: |\n Deprecated: legacy FTP-scoped PGP private key. Superseded by the connection-level `pgp.privateKey`;\n retained for the few existing connections still on this path (encrypted at rest).\n writeOnly: true\n x-celigo-ai-guidance:\n - |-\n PGP private key for decrypting files after download (encrypted at rest).\n When set, downloaded files are automatically PGP-decrypted.\n pgpPassphrase:\n type: string\n deprecated: true\n description: 'Deprecated: legacy FTP-scoped PGP passphrase. Superseded by the connection-level `pgp.passphrase` (encrypted at rest; returned masked as `\"******\"`).'\n pgpKeyAlgorithm:\n type: string\n deprecated: true\n enum:\n - CAST5\n - 3DES\n - AES-128\n - AES-192\n - AES-256\n x-enumDescriptions:\n CAST5: CAST5 symmetric cipher (PGP default, 128-bit key).\n 3DES: Triple DES symmetric cipher (168-bit effective key strength).\n AES-128: AES symmetric cipher with a 128-bit key.\n AES-192: AES symmetric cipher with a 192-bit key.\n AES-256: AES symmetric cipher with a 256-bit key (strongest option).\n description: |\n Deprecated: legacy FTP-scoped PGP encryption-algorithm selector, no longer exposed by the\n connection form (the current `pgp` object has no algorithm field). Retained for existing\n connections. AES-256 is the strongest option; CAST5 is the PGP default.\n x-celigo-ai-guidance:\n - |-\n Symmetric encryption algorithm used for PGP operations.\n AES-256 is recommended for strong encryption. CAST5 is the PGP default.\n Must match the algorithm expected by the recipient when encrypting.\n pgpSignAndVerify:\n type: boolean\n deprecated: true\n description: |\n Deprecated: legacy FTP-scoped PGP sign/verify toggle, no longer exposed by the connection form.\n When true, PGP-signs outbound files and verifies signatures on inbound files. Retained for\n existing connections.\n default: false\n x-celigo-ai-guidance:\n - |-\n When true, PGP-signs outbound files and verifies signatures on inbound files.\n Provides authenticity and integrity verification on top of encryption.\n tradingPartner:\n type: boolean\n readOnly: true\n description: |\n When true, this connection is designated a B2B/EDI trading partner. Read-only on the connection\n body — POST/PUT of this field are silently ignored; it is toggled via\n `PUT /connections/{_id}/tradingPartner` (used by the EDI B2B Manager).\n _tpConnectorId:\n type: string\n format: objectId\n x-celigo-refModel: tradingpartnerconnectors\n description: |\n Reference to the trading partner connector this connection belongs to. Must reference an\n existing, published trading partner connector; the API rejects an unknown or unpublished ID\n with 422 `tpconnector_not_found`.\n examples: [\"66a1b2c3d4e5f60718293a4b\"]\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent file transfer operations.\n FTP servers often have low connection limits — keep this value conservative.\n Send no more than the account's licensed maximum, the license's `concurrency` (25 standard,\n 50 with an Environments license).\n While `autoRecoverRateLimitErrors` is true, which a create gets unless it sends `false`, a create\n ignores the value sent here and sets this field to `targetConcurrencyLevel`, or to 1 when no\n target is sent. To start higher, send `targetConcurrencyLevel` too, or create with\n `autoRecoverRateLimitErrors: false`.\n Unlike the rest of the `ftp` object, a `PUT` that omits this field keeps the stored value instead of clearing it.\n minimum: 1\n maximum: 50\n default: 1\n examples: [3]\n targetConcurrencyLevel:\n type: integer\n description: |\n While `autoRecoverRateLimitErrors` is true, a create sets `concurrencyLevel` to this value, and a\n create that omits it gets 1 for both. Auto-recovery never runs on FTP connections (FTP errors\n aren't treated as rate limits), so nothing climbs back to it.\n Kept on a `PUT` that omits it, like `concurrencyLevel`; unset by the save while\n `autoRecoverRateLimitErrors` is false.\n minimum: 1\n maximum: 50\n examples: [5]\n multiThreadCount:\n type: integer\n minimum: 1\n description: |-\n Number of parallel transfer threads for this FTP connection. Must be a\n whole number — decimals are rejected on save. Send no more than the\n account's licensed concurrency maximum, the same as for `concurrencyLevel`. On\n save the value is mirrored into `userConcurrencyLevel` (and into\n `userTargetConcurrencyLevel` when auto-recovery of rate-limit errors\n is active with `targetConcurrencyLevel` set); clearing it clears the\n mirrors. Not preserved across a `PUT` — re-send it with the rest of\n the `ftp` object or it is cleared.\n examples: [2]\n userConcurrencyLevel:\n type: integer\n readOnly: true\n description: |-\n Server-maintained mirror of `multiThreadCount`. Present when\n `multiThreadCount` is set; do not send it — it is recomputed on save.\n userTargetConcurrencyLevel:\n type: integer\n readOnly: true\n description: |-\n Server-maintained mirror of `multiThreadCount`, present while\n `autoRecoverRateLimitErrors` is true and `targetConcurrencyLevel` is\n set; recomputed on save.\n # Conditional requireds mirror the connection form (see x-celigo-ui-override). Stack-style\n # top-level if/then/else; GitBook ignores it, downstream consumers get form-accurate validation.\n # Form rule: sftp needs password or authKey; ftp/ftps need password.\n if:\n properties:\n type:\n const: sftp\n required: [type]\n then:\n anyOf:\n - required: [password]\n - required: [authKey]\n else:\n required: [password]\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":13589,"content_sha256":"95fb3225e139e6299cdaeb9b3386bc71ae19a89b477e043c9d1d1800d6ce2257"},{"filename":"references/schemas/http.yml","content":"HTTP:\n type: object\n description: |-\n Configuration for HTTP/REST API connections. Used when the connection type is \"http\".\n This is the most versatile connection type in Celigo, supporting any REST, SOAP, or generic HTTP API.\n The auth.type field selects the authentication strategy; each type requires specific sub-fields.\n x-celigo-ai-guidance:\n - Use for APIs not covered by a specialized connector, GraphQL APIs (formType \"graph_ql\"), and Amazon Selling Partner API connections.\n - |-\n When scaffolding a flow before the user has provisioned a real Amazon account, set type to\n \"Amazon-Hybrid\", populate unencrypted.marketplaceId (\"ATVPDKIKX0DER\") and\n unencrypted.sellingRegion (\"northAmerica\"), and let the user finish the connection in the\n Celigo UI. Omitting either field fails the POST with 422 \"Expected field: marketplaceId to be present\".\n x-celigo-ui-override: >-\n The auth.type conditional below encodes the connection form's credential requireds. Most are also\n API-enforced; the form-only additions (the API creates the connection without them, or accepts a\n weaker rule) are auth.basic.password (the API accepts a username alone), auth.token.location,\n auth.token.headerName (wsse), auth.cookie.method, auth.cookie.body, and _iClientId (oauth) —\n each flagged on its own field. _iClientId for awsiam is both form- and API-required.\n required:\n - baseURI\n - mediaType\n properties:\n mediaType:\n type: string\n enum:\n - xml\n - json\n - urlencoded\n - form-data\n - plaintext\n x-enumDescriptions:\n xml: Serialize request bodies as application/xml; use for SOAP or XML APIs.\n json: Serialize request bodies as application/json; use for most modern REST APIs.\n urlencoded: Serialize request bodies as application/x-www-form-urlencoded; use for form-style POST bodies.\n form-data: Serialize request bodies as multipart/form-data; use for file uploads.\n plaintext: Send request bodies as text/plain with no serialization.\n description: |-\n Default content type for outbound HTTP request bodies.\n Controls the Content-Type header and how request bodies are serialized.\n x-celigo-ai-guidance:\n - Default mediaType to \"json\" unless the API documentation specifies otherwise.\n x-lowercase: true\n examples:\n - json\n successMediaType:\n type: string\n enum:\n - xml\n - csv\n - json\n - plaintext\n x-enumDescriptions:\n xml: Parse successful responses as XML.\n csv: Parse successful responses as CSV.\n json: Parse successful responses as JSON.\n plaintext: Treat successful responses as raw text with no parsing.\n description: |-\n Expected content type of successful API responses. Controls how response bodies are parsed.\n If omitted, the system infers the format from the response Content-Type header.\n x-lowercase: true\n examples:\n - json\n errorMediaType:\n type: string\n enum:\n - xml\n - json\n - plaintext\n x-enumDescriptions:\n xml: Parse error responses as XML.\n json: Parse error responses as JSON.\n plaintext: Treat error responses as raw text with no parsing.\n description: |\n Expected content type of error responses from the API. Controls how error response bodies are parsed for extracting error messages.\n\n If omitted, defaults to the same format as successMediaType.\n x-lowercase: true\n examples:\n - json\n baseURI:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n Base URL for all API requests made through this connection. Required.\n\n All relative URIs in exports and imports are appended to this base URL.\n Must be an absolute URL (e.g., \"https://api.example.com/v2\").\n Handlebars expressions are supported for dynamic URLs — e.g.\n \"https://{{{connection.settings.subdomain}}}.example.com\".\n\n Do NOT include trailing slashes — relative URIs in exports/imports should start with \"/\".\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n examples:\n - https://api.example.com/v2\n - https://{{{connection.settings.subdomain}}}.zendesk.com\n disableStrictSSL:\n type: boolean\n description: |\n When true, disables strict SSL/TLS certificate validation for API requests.\n\n Only set to true for development/testing with self-signed certificates.\n NEVER disable in production — it removes protection against man-in-the-middle attacks.\n default: false\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent HTTP requests this connection can make simultaneously.\n\n Higher values increase throughput but may trigger API rate limits.\n Set this based on the target API's rate limit documentation.\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n A decimal is rejected with 422 `invalid_field_value` on every write (the same rule applies to every\n adaptor's `concurrencyLevel` and `targetConcurrencyLevel`, and to `ftp.multiThreadCount`).\n Platform-managed while `autoRecoverRateLimitErrors` is true — a create or PUT ignores the value (a create without `targetConcurrencyLevel` stores 25 where the license's `concurrency` is at least 25) and the recovery machinery moves it toward the target; set `targetConcurrencyLevel` instead.\n At level 1 an import's pages run one at a time, so a record's existence lookup and write finish before the next record's start (measured on a single import); the import's `idLockTemplate` serializes only same-key records and leaves the rest parallel.\n minimum: 1\n maximum: 50\n default: 25\n examples:\n - 10\n targetConcurrencyLevel:\n type: integer\n description: |\n Ceiling the platform climbs back to after rate-limit recovery, in steps of 25% of this value.\n Writing it also sets `concurrencyLevel` to the same value and stops any recovery in progress.\n\n Honored only while `autoRecoverRateLimitErrors` is true; ignored, and unset, when it is false.\n minimum: 1\n maximum: 50\n examples:\n - 10\n retryHeader:\n type: string\n description: |\n HTTP response header name that contains the retry delay (in seconds) when rate-limited.\n\n Defaults to \"Retry-After\" which is the HTTP standard. Only change this if the API\n uses a non-standard header name for retry-after values.\n default: \"Retry-After\"\n formType:\n type: string\n enum:\n - assistant\n - rest\n - http\n - graph_ql\n - assistant_graphql\n x-enumDescriptions:\n assistant: Application assistant form with pre-configured settings.\n rest: Simplified REST connector form linked to an HTTP connector template.\n http: Standard HTTP connection form with full control over all fields.\n graph_ql: GraphQL-specific form with query and mutation support.\n assistant_graphql: Application assistant form with GraphQL support.\n description: |-\n Controls the UI form layout for configuring this connection. Determines which\n fields are shown and how they are organized in the Celigo UI.\n For programmatic creation, http is the most common choice.\n x-celigo-ai-guidance:\n - |-\n The value selects a form, not a protocol: a plain `http` connection sends GraphQL requests\n identically. What `graph_ql` adds is the GraphQL editing experience — the connection form\n authors the ping as Query / Operation name / Variables fields compiled into `http.ping.body`,\n and every export and import on the connection gets a Form view toggle between the GraphQL\n editor (Query / Operation name / Variables) and the raw HTTP form.\n - |-\n A `graph_ql` connection's `baseURI` should be the GraphQL endpoint itself\n (`https://host/graphql`, `https://\u003cstore>.myshopify.com/admin/api/\u003cversion>/graphql.json`):\n the GraphQL export and import forms have no relative URI field.\n - |-\n The connection form offers no control to change this value on a connection without an HTTP\n connector, and connections cannot be cloned through the API. A user who wants the GraphQL\n editor for steps that live on an `http` connection needs a new `graph_ql` connection (same\n base URI and auth, credentials re-entered) with the steps re-pointed to it — this is the\n setup to recommend, not a product gap.\n x-lowercase: true\n examples:\n - http\n type:\n type: string\n enum:\n - Amazon-SP-API\n - Amazon-Hybrid\n - vendor_central\n x-enumDescriptions:\n Amazon-SP-API: Amazon Seller Central over the Selling Partner API, authorized against Celigo's registered application through Login with Amazon\n Amazon-Hybrid: Amazon Seller Central over both the legacy MWS and the Selling Partner API, for integrations not yet fully on SP-API\n vendor_central: Amazon Vendor Central over the Selling Partner API, authorized against Celigo's registered application through Login with Amazon\n description: |-\n Selects which Amazon selling program and API family a prebuilt Amazon connection talks to.\n Set by the Amazon Seller Central and Amazon Vendor Central connection forms; a custom\n Selling Partner API integration built on the customer's own developer application is a\n plain HTTP connection and does not carry this field.\n x-celigo-ai-guidance:\n - |-\n The prebuilt Amazon connection forms collect the API type, selling region and marketplace\n and save an OAuth 2.0 authorization-code connection (`http.auth.type` `oauth`,\n `http.auth.oauth.grantType` `authorizecode`) whose authorization URI is the Seller Central\n or Vendor Central `/apps/authorize/consent` page: Amazon's public-application consent,\n granted by the selling partner to Celigo's registered Selling Partner API application. For\n `vendor_central` the create request omits `http._iClientId` — the customer never sends\n one — and the connector writes Celigo's published Global iClient onto the saved\n connection as `http._iClientId` (`useIClientFields` true), so the saved document does\n carry an iClient id, Celigo's. Celigo's Seller\n Central documentation states the customer need not register as an Amazon developer\n (article 360060827012); the Vendor Central form carries no developer credentials either.\n - |-\n The prebuilt forms collect no Amazon developer application id, client secret, AWS\n credentials or customer-owned iClient (the Seller Central form offers an iClient field\n only for its legacy `Amazon-MWS` choice), so creating one of these connections asks the\n customer for a Seller Central or Vendor Central account for the chosen region and\n marketplace and a user who can complete Amazon's consent screen — for Vendor Central, a\n user holding the Manage Integrations (EDI/API) permission for the vendor group the\n integration should reach. Amazon requires public applications to be re-authorized every\n 365 days; the customer re-runs the authorization from the existing connection and nothing\n else changes. A customer who must run on their OWN developer registration builds a\n token-based or OAuth 2.0 universal HTTP connection to the Selling Partner API base URI\n instead (articles 6204088366363 and the OAuth 2.0 universal connector) and takes on\n Amazon's developer agreements themselves.\n examples:\n - Amazon-SP-API\n clientCertificates:\n type: object\n description: |\n Client certificate configuration for mutual TLS (mTLS) authentication.\n\n Use when the API server requires a client certificate to establish the TLS connection.\n You can provide either a PEM cert/key pair OR a PFX bundle, but not both.\n properties:\n cert:\n type: string\n description: |\n Client certificate in PEM format. Must be paired with the key field.\n Cannot be used together with pfx.\n key:\n type: string\n description: Private key for the client certificate in PEM format (encrypted at rest).\n writeOnly: true\n ca:\n type: string\n description: |\n Certificate Authority (CA) certificate in PEM format.\n Use when the server's certificate is signed by a private CA not in the default trust store.\n passphrase:\n type: string\n description: Passphrase to decrypt an encrypted private key or PFX bundle (encrypted at rest).\n writeOnly: true\n examples:\n - s3cr3t-passphrase\n pfx:\n type: string\n description: |\n PKCS#12 (.pfx/.p12) bundle containing both the certificate and private key (encrypted at rest).\n Cannot be used together with cert/key.\n writeOnly: true\n ping:\n type: object\n description: |\n Connection health check (ping) configuration. Defines how Celigo tests\n whether this connection is alive and authenticated.\n\n When configured, Celigo sends an HTTP request to the specified endpoint and\n evaluates the response to determine connection health. The ping runs when\n testing the connection in the UI and periodically during flow execution.\n properties:\n relativeURI:\n type:\n - string\n - \"null\"\n x-celigo-agent:\n - handlebars\n description: |\n Relative URI appended to baseURI for the ping request.\n Should be a lightweight, fast endpoint (e.g., \"/me\", \"/health\", \"/api/v1/status\").\n May be null when no ping endpoint is configured.\n examples:\n - /me\n method:\n type: string\n enum:\n - GET\n - POST\n - PUT\n - HEAD\n x-enumDescriptions:\n GET: Send a GET request to the ping endpoint.\n POST: Send a POST request to the ping endpoint.\n PUT: Send a PUT request to the ping endpoint.\n HEAD: Send a HEAD request to check endpoint availability without a response body.\n description: |\n HTTP method for the ping request. Defaults to GET.\n Use POST only if the health endpoint requires it.\n default: GET\n x-uppercase: true\n examples:\n - GET\n body:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n Request body for the ping request. Only used when method is POST or PUT.\n For form-data mediaType, must be valid multipart form data.\n examples:\n - '{\"query\":\"{ __typename }\"}'\n successPath:\n type: string\n description: |\n JSON path or XPath expression to extract a success indicator from the ping response.\n If the value at this path matches one of the successValues, the ping succeeds.\n If omitted, any 2xx response is considered successful.\n examples:\n - status\n successValues:\n type: array\n items:\n type: string\n description: |\n Values that indicate a successful ping when found at successPath.\n Requires successPath to be set.\n examples:\n - [ok, healthy]\n allowArrayforSuccessPath:\n type: boolean\n description: When true, the value at successPath can be an array and any matching element counts as success.\n failPath:\n type: string\n description: |\n JSON path or XPath expression to extract a failure indicator from the ping response.\n If the value at this path matches one of the failValues, the ping fails even if the HTTP status is 2xx.\n examples:\n - error.code\n failValues:\n type: array\n items:\n type: string\n description: |\n Values that indicate a failed ping when found at failPath.\n Requires failPath to be set.\n examples:\n - [unauthorized, forbidden]\n errorPath:\n type: string\n description: |\n JSON path or XPath expression to extract a human-readable error message from\n a failed ping response. The extracted message is shown to the user in the UI.\n examples:\n - error.message\n auth:\n type: object\n description: |\n Authentication configuration for the API connection.\n\n The auth.type field selects the authentication strategy. Each type requires\n specific sub-fields — see the type field description for details.\n properties:\n type:\n type: string\n enum:\n - custom\n - basic\n - token\n - oauth\n - wsse\n - cookie\n - jwt\n - digest\n - specific\n - oauth1\n - jwtbearer\n - awsiam\n x-celigo-deprecated-enum-values:\n # `jwt` is the legacy JWT auth type, superseded by `jwtbearer`. Kept in source (older\n # connections may still report it) but stripped from the published bundle: the HTTP\n # connection form no longer offers it (the Auth type dropdown lists jwtbearer, not jwt).\n # New consumers should use jwtbearer.\n - jwt\n # `specific` is an API-only auth type exposed by no connection form (absent from the\n # http/httpFramework/graphql/salesforce form defs and the connection field definitions).\n # Kept in source for any record that may still carry it; stripped from publish.\n - specific\n x-enumDescriptions:\n custom: No built-in auth; credentials are placed in headers or encrypted fields.\n basic: HTTP Basic Authentication; requires auth.basic.username and auth.basic.password.\n token: API key or bearer token; requires auth.token (value and location); supports auto-refresh via auth.token.refreshMethod.\n oauth: OAuth 2.0 authentication supporting authorization code, client credentials, and password grants.\n wsse: WS-Security UsernameToken authentication for SOAP APIs.\n cookie: Cookie-based session authentication; requires auth.cookie.uri for the login endpoint.\n jwt: Legacy JWT authentication (prefer jwtbearer for new connections).\n digest: HTTP Digest Authentication; requires auth.basic.username and auth.basic.password.\n specific: Legacy API-only auth type; not offered by any connection form (retained for records that may still report it).\n oauth1: OAuth 1.0a authentication with HMAC or RSA signatures.\n jwtbearer: JWT Bearer Token authentication with configurable signing algorithms.\n awsiam: AWS Signature v4 request signing using credentials from an AWS-IAM iClient; requires http._iClientId.\n description: |-\n Authentication method for this connection. Determines which auth sub-fields are required.\n Each type has its own credential fields; see the x-enumDescriptions for details.\n x-lowercase: true\n x-celigo-ai-guidance:\n - |-\n When type is \"awsiam\", the connection must also carry http._iClientId pointing at\n an iClient with provider \"awsIam\" that belongs to the same account and has\n awsIam.roleArn whose role name starts with \"celigo-http-adaptor-\"; the save fails\n with 422 (missing_required_field, invalid_field, invalid_field_value, or invalid_ref\n respectively) when any of these is off. The signing credentials live on the iClient,\n not on the connection.\n examples:\n - token\n failStatusCode:\n type: number\n description: |\n HTTP status code that indicates an authentication failure (e.g., 401, 403).\n When this status code is received, the system triggers re-authentication\n before retrying the request.\n examples:\n - 401\n failPath:\n type: string\n description: |\n JSON path or XPath expression to check in response bodies for authentication failure indicators.\n Used when APIs return 200 OK but embed auth errors in the response body.\n examples:\n - error.code\n failValues:\n type: array\n items:\n type: string\n description: |\n Values at failPath that indicate an authentication failure.\n Requires failPath to be set.\n examples:\n - [invalid_token, expired_token]\n failures:\n type: array\n description: |\n HTTP status codes that indicate an authentication failure and should trigger\n re-authentication. An alternative to failStatusCode that accepts multiple codes.\n items:\n type: object\n properties:\n statusCode:\n type: number\n description: HTTP status code that signals an authentication failure (e.g., 403).\n examples:\n - 403\n skipFollowAuthorizationHeader:\n type: boolean\n description: |\n When true, the Authorization header is NOT forwarded on HTTP redirects.\n Enable this for APIs that redirect to a different domain after authentication.\n basic:\n type: object\n description: |\n Basic authentication credentials. Required when auth.type is \"basic\", \"wsse\", or \"digest\".\n properties:\n username:\n type: string\n description: Username for Basic/Digest/WSSE authentication.\n examples:\n - svc_account\n password:\n type: string\n description: |-\n Password for Basic/Digest/WSSE authentication (encrypted at rest). On update, the\n masked `\"******\"` sent back keeps the stored password; a new value replaces it.\n writeOnly: true\n examples:\n - s3cr3t-p4ssw0rd\n x-celigo-ui-override: >-\n Required by the connection form for basic/digest/wsse auth. The API enforces only\n that basic contains a username or a password (it accepts a username alone), so the\n password requirement here mirrors the form to produce connectable configurations.\n token:\n type: object\n description: |\n Token-based authentication configuration. Required when auth.type is \"token\".\n\n Supports static API keys/bearer tokens and automatic token refresh flows.\n The token can be sent in a header (Authorization), query parameter, or request body.\n properties:\n token:\n type: string\n description: |\n The API key or bearer token value (encrypted at rest); returned masked as `\"******\"`.\n On update, the mask sent back keeps the stored token; a new value replaces it.\n Required unless automatic token refresh is configured: a token block without a\n token must carry a `refreshMethod`, so a create or update that sends neither fails\n with 422 `Expected field: refreshMethod to be present.` To create a static-token\n connection before the real token is available, send a placeholder value and\n replace it later.\n examples:\n - my-api-token-EXAMPLE\n location:\n type: string\n enum:\n - url\n - header\n - body\n x-enumDescriptions:\n url: Include the token as a URL query parameter.\n header: Include the token in an HTTP header (most common).\n body: Include the token in the request body.\n description: |-\n Where to include the token in outbound requests.\n Most APIs expect header. Use headerName and scheme to control the header format,\n or paramName when sending as a URL query parameter.\n examples:\n - header\n x-celigo-ui-override: >-\n Required by the connection form for token auth; the API accepts a static token without it.\n headerName:\n type: string\n description: |\n HTTP header name for the token when location is \"header\".\n Defaults to \"Authorization\" if omitted.\n examples:\n - Authorization\n x-celigo-ui-override: >-\n Required by the connection form when location is \"header\"; also where wsse auth stores\n its header name (default \"X-WSSE\"). The API does not enforce it.\n scheme:\n type: string\n description: |\n Token scheme/prefix when sent in a header. Prepended before the token value.\n Common values: \"Bearer\", \"Token\", \"Basic\".\n Example: scheme \"Bearer\" produces header \"Authorization: Bearer \u003ctoken>\".\n examples:\n - Bearer\n paramName:\n type: string\n description: |\n Query parameter name for the token when location is \"url\".\n Example: paramName \"api_key\" produces URL \"?api_key=\u003ctoken>\".\n examples:\n - access_token\n refreshMethod:\n type: string\n enum:\n - GET\n - POST\n - PUT\n x-enumDescriptions:\n GET: Use a GET request to refresh the token.\n POST: Use a POST request to refresh the token.\n PUT: Use a PUT request to refresh the token.\n description: |\n HTTP method for automatic token refresh requests.\n Required when no static token is provided (refresh-based auth flow).\n default: POST\n x-uppercase: true\n examples:\n - POST\n refreshRelativeURI:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n Relative URI (appended to baseURI) for the token refresh endpoint.\n The system calls this endpoint to obtain a new token when the current one expires.\n examples:\n - /oauth2/token\n refreshBody:\n type: string\n x-celigo-agent:\n - handlebars\n description: Request body to send with the token refresh request.\n examples:\n - grant_type=refresh_token&refresh_token={{{connection.http.auth.token.refreshToken}}}\n refreshMediaType:\n type: string\n enum:\n - json\n - urlencoded\n - xml\n - plaintext\n x-enumDescriptions:\n json: Send the refresh request body as application/json.\n urlencoded: Send the refresh request body as application/x-www-form-urlencoded.\n xml: Send the refresh request body as application/xml.\n plaintext: Send the refresh request body as text/plain.\n description: |\n Content type for the token refresh request body.\n default: urlencoded\n x-lowercase: true\n examples:\n - urlencoded\n refreshResponseMediaType:\n type: string\n enum:\n - json\n - xml\n x-enumDescriptions:\n json: Parse the token refresh response as JSON.\n xml: Parse the token refresh response as XML.\n description: Expected content type of the token refresh response.\n x-lowercase: true\n examples:\n - json\n refreshTokenPath:\n type: string\n description: |\n JSON path to extract the new token from the refresh response.\n Example: \"access_token\" or \"data.token\".\n examples:\n - data.access_token\n refreshToken:\n type: string\n description: Refresh token used to obtain a new access token (encrypted at rest).\n writeOnly: true\n examples:\n - rt_abc123EXAMPLE456refresh\n refreshTokenLocation:\n type: string\n enum:\n - header\n - body\n x-enumDescriptions:\n header: Include the refresh token in an HTTP header.\n body: Include the refresh token in the request body.\n description: Where to include the refresh token in refresh requests.\n examples:\n - body\n refreshHeaders:\n type: array\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name to send with the token-refresh request.\n examples:\n - Content-Type\n value:\n type: string\n x-celigo-agent:\n - handlebars\n description: Header value to send with the token-refresh request.\n examples:\n - application/x-www-form-urlencoded\n description: Additional headers to include in token refresh requests.\n tokenPaths:\n type: array\n items:\n type: string\n description: |\n JSON paths to extract multiple token values from the refresh response.\n Use when the refresh response contains tokens at different paths that need\n to be stored for subsequent requests.\n examples:\n - [access_token, refresh_token]\n revoke:\n type: object\n description: |\n Token-revocation request configuration. When set, the system calls this\n endpoint to revoke the current token (e.g. when the connection is deleted or\n re-authenticated). Used mainly by pre-built HTTP Connector templates.\n properties:\n uri:\n type: string\n x-celigo-agent:\n - handlebars\n description: Absolute URL of the token-revocation endpoint.\n examples:\n - https://api.example.com/oauth2/revoke\n body:\n type: string\n x-celigo-agent:\n - handlebars\n description: Request body to send with the token-revocation request.\n examples:\n - token={{{connection.http.auth.token.token}}}\n headers:\n type: array\n description: Additional headers to include in the token-revocation request.\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name to send with the revocation request.\n examples:\n - Content-Type\n value:\n type: string\n x-celigo-agent:\n - handlebars\n description: Header value to send with the revocation request.\n examples:\n - application/x-www-form-urlencoded\n oauth:\n $ref: './oauth.yml#/OAuth'\n cookie:\n type: object\n description: |\n Cookie-based session authentication. Required when auth.type is \"cookie\".\n\n The system authenticates by sending a request to the login URI, captures the\n session cookies from the response, and includes them in all subsequent API requests.\n properties:\n uri:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n Login endpoint URI for cookie authentication. Required.\n The system sends a request to this URI to obtain session cookies.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol;\n data sent to an HTTP endpoint is not encrypted and may be intercepted or\n modified in transit.\n examples:\n - https://api.example.com/login\n body:\n type: string\n x-celigo-agent:\n - handlebars\n description: Request body for the login request (e.g., JSON with username/password).\n examples:\n - '{\"username\":\"svc_account\",\"password\":\"{{{connection.http.encrypted.password}}}\"}'\n x-celigo-ui-override: >-\n Required by the connection form when method is \"POST\"; the API does not enforce it.\n method:\n type: string\n description: HTTP method for the login request (typically POST).\n examples:\n - POST\n x-celigo-ui-override: >-\n Required by the connection form for cookie auth; the API accepts cookie auth with only uri.\n successStatusCode:\n type: number\n description: |\n HTTP status code that confirms successful authentication.\n If the login response returns this status code, the session cookies are captured.\n examples:\n - 200\n jwt:\n $ref: './jwt.yml#/JWT'\n # auth.type credential matrix — else-if (no allOf).\n # basic/digest/wsse -> basic.username+password; token -> token.token; cookie -> cookie.uri;\n # jwtbearer -> jwt.signatureMethod+payload (+secret for hmac-*, +privateKey for rsa/ps/es);\n # oauth1 -> oauth.oauth1.signatureMethod+consumerKey+accessToken (+consumerPrivateKey for rsa-*,\n # +consumerSecret+tokenSecret otherwise). oauth/custom/specific have no API-enforced auth requireds.\n if:\n properties:\n type:\n enum:\n - basic\n - digest\n - wsse\n required:\n - type\n then:\n required:\n - basic\n properties:\n basic:\n required:\n - username\n - password\n else:\n if:\n properties:\n type:\n const: token\n required:\n - type\n then:\n required:\n - token\n properties:\n token:\n required:\n - token\n - location\n else:\n if:\n properties:\n type:\n const: cookie\n required:\n - type\n then:\n required:\n - cookie\n properties:\n cookie:\n required:\n - uri\n else:\n if:\n properties:\n type:\n const: jwtbearer\n required:\n - type\n then:\n required:\n - jwt\n properties:\n jwt:\n required:\n - signatureMethod\n - payload\n if:\n properties:\n jwt:\n properties:\n signatureMethod:\n enum:\n - hmac-sha256\n - hmac-sha384\n - hmac-sha512\n required:\n - signatureMethod\n required:\n - jwt\n then:\n properties:\n jwt:\n required:\n - signatureMethod\n - payload\n - secret\n else:\n properties:\n jwt:\n required:\n - signatureMethod\n - payload\n - privateKey\n else:\n if:\n properties:\n type:\n const: oauth1\n required:\n - type\n then:\n required:\n - oauth\n properties:\n oauth:\n required:\n - oauth1\n properties:\n oauth1:\n required:\n - signatureMethod\n - consumerKey\n - accessToken\n if:\n properties:\n oauth:\n properties:\n oauth1:\n properties:\n signatureMethod:\n enum:\n - rsa-sha1\n - rsa-sha256\n - rsa-sha512\n required:\n - signatureMethod\n required:\n - oauth1\n required:\n - oauth\n then:\n properties:\n oauth:\n properties:\n oauth1:\n required:\n - signatureMethod\n - consumerKey\n - accessToken\n - consumerPrivateKey\n else:\n properties:\n oauth:\n properties:\n oauth1:\n required:\n - signatureMethod\n - consumerKey\n - accessToken\n - consumerSecret\n - tokenSecret\n rateLimit:\n type: object\n description: |\n Rate limiting configuration. Defines how the system detects and handles\n API rate limit responses.\n\n When rate limiting is detected, the system pauses requests and waits for\n the retry-after period before resuming. The retryHeader field on the parent\n HTTP object controls which response header contains the wait time.\n properties:\n failStatusCode:\n type: number\n description: |\n HTTP status code that indicates the API is rate-limiting requests.\n Defaults to 429 (Too Many Requests) which is the HTTP standard.\n Change only if the API uses a non-standard status code for rate limits.\n default: 429\n failPath:\n type: string\n description: |\n JSON path or XPath to check in response bodies for rate limit indicators.\n Used when APIs return 200 OK but embed rate limit errors in the response body.\n examples:\n - errors[0].code\n failValues:\n type: array\n items:\n type: string\n description: |\n Values at failPath that indicate rate limiting. Requires failPath to be set.\n examples:\n - [rate_limit_exceeded, too_many_requests]\n limit:\n type: number\n minimum: 1\n description: |\n Maximum number of requests per rate-limit window. When set, the connection's\n effective concurrency level must be 1 to ensure proper rate limit enforcement.\n examples:\n - 1000\n headers:\n type: array\n description: |\n Default HTTP headers included in every request made through this connection.\n Use for API keys in custom headers, content negotiation, or any headers the API requires on all requests.\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name (e.g., \"X-API-Key\", \"Accept\").\n examples:\n - X-API-Key\n value:\n type: string\n x-celigo-agent:\n - handlebars\n description: Header value. Supports handlebars expressions for dynamic values.\n examples:\n - '{{{connection.http.encrypted.apiKey}}}'\n required:\n - name\n - value\n encrypted:\n type:\n - object\n - string\n description: |\n Encrypted custom fields for storing sensitive configuration values (API secrets,\n private keys, etc.) that don't fit standard auth fields. Sent as an object of\n field-name/value pairs; values are encrypted at rest. Returned as the masked\n string `\"******\"` on responses; on update, that mask sent back keeps the stored values,\n and a new object replaces them. Field definitions are specified in encryptedFields.\n examples:\n - {apiSecret: s3cr3t-value, signingKey: another-s3cr3t}\n encryptedFields:\n type: array\n description: |\n Metadata defining the encrypted custom fields available on this connection.\n Each entry describes a field in the encrypted object — its ID, label, and UI position.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the encrypted object.\n examples:\n - apiSecret\n label:\n type: string\n description: Human-readable label shown in the UI.\n examples:\n - API secret\n required:\n type: boolean\n default: false\n description: When true, the custom field defined by this entry is mandatory — a value for it must be supplied before the connection can be saved.\n position:\n type: number\n description: Display order in the UI form.\n examples:\n - 0\n helpText:\n type: string\n description: Tooltip or help text shown next to the field in the UI.\n examples:\n - Find this in your provider's developer console.\n unencrypted:\n type: object\n description: |-\n Unencrypted custom fields for non-sensitive configuration values.\n Field definitions are specified in unencryptedFields.\n properties:\n marketplaceId:\n type: string\n description: Amazon marketplace identifier for Amazon connection types.\n examples: [\"ATVPDKIKX0DER\", \"A1F83G8C2ARO7P\", \"A1PA6795UKMFR9\"]\n sellingRegion:\n type: string\n description: Amazon selling region for the marketplace.\n examples: [\"northAmerica\", \"europe\", \"farEast\"]\n googleProjectId:\n type: string\n description: |-\n Google Cloud project id for Google Cloud Storage connections\n (assistant `googlecloudstorage`, or a `baseURI` pointing at\n `storage.googleapis.com`).\n examples: [\"my-gcs-project\"]\n x-celigo-ai-guidance:\n - |-\n Required when the GCS connection authenticates through an OAuth\n iClient (provider custom_oauth2). Omitting it fails the save\n with 422 project_id_missing on http.unencrypted.googleProjectId\n — \"Default project ID is required on OAuth Google Cloud Storage\n connections (http.unencrypted.googleProjectId).\" With a\n googleserviceaccount iClient the server fills this from the\n key's project_id. Any other provider fails with 422\n invalid_field on http._iClientId — \"IClient provider must be\n googleserviceaccount or custom_oauth2 for Google Cloud Storage\n connections.\"\n unencryptedFields:\n type: array\n description: |\n Metadata defining the unencrypted custom fields available on this connection.\n Each entry describes a field in the unencrypted object.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the unencrypted object.\n examples:\n - accountId\n label:\n type: string\n description: Human-readable label shown in the UI.\n examples:\n - Account ID\n required:\n type: boolean\n default: false\n description: When true, the custom field defined by this entry is mandatory — a value for it must be supplied before the connection can be saved.\n position:\n type: number\n description: Display order in the UI form.\n examples:\n - 0\n helpText:\n type: string\n description: Tooltip or help text shown next to the field in the UI.\n examples:\n - Your numeric account identifier.\n type:\n type: string\n description: Field type hint for the UI (e.g., \"text\", \"select\").\n examples:\n - text\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n description: |-\n iClient that holds the credentials this connection signs with: the OAuth 2.0 client for\n `auth.type` `oauth` (including the `azureserviceprincipal` service principal an Azure\n Data Lake Storage Gen2 connection authenticates with and the `googleserviceaccount` key\n a Google Cloud Storage connection uses), or the `awsIam` role for `auth.type` `awsiam`.\n Must belong to the same account as the connection — or be the iClient Celigo publishes\n with a pre-built OAuth HTTP connector (pre-configured by the connector; from the\n connecting account `GET /v1/iclients/{_id}` on it is 404 resource_not_found and\n `GET /v1/iclients` does not list it, yet the connection saves with it). Omit for every\n other auth type. On a Shopify connection `settings.appType` says which of the two it\n is: `public` rides Celigo's published Shopify app (installed from the Shopify App\n Store), `custom` rides the account's own iClient — the Shopify app the customer created\n in the Shopify dev dashboard — with `auth.oauth.scope` chosen on the connection. A\n connection with no `settings.appType` (saved before the App type existed) rides the\n published app when its `_iClientId` is the connector's published iClient — the form\n opens it with no App type selected and it keeps working — and an account-owned iClient\n otherwise. A saved Public App connection, with or without a stored `settings.appType`,\n moves to the customer's app by the same re-save: `settings.appType` `custom`, its own\n `_iClientId` and scopes, then authorizing; the connection form does not offer the\n reverse, because the Public App flow is authorized from the Shopify App Store and\n creates a new connection. Integration App connections (`_connectorId`) stay on Celigo's\n published app and carry no `settings.appType`.\n examples:\n - 6203a7e4f321d800129a1b8e\n x-celigo-ui-override: >-\n Required by the connection form for oauth (subForms/httpOAuth.js: required true, iClient\n filter provider custom_oauth2, or googleserviceaccount / azureserviceprincipal for the\n GCS and ADLS Gen2 variants) and for awsIam (subForms/httpAwsIam.js: required true,\n filter provider awsIam). For oauth the API creates the connection without it and the\n authorization is completed afterward; for awsiam the API also rejects its absence (see\n the if/then rule on this schema).\n x-celigo-ai-guidance:\n - |-\n For auth.type \"awsiam\" the referenced iClient must have provider \"awsIam\" (any other\n provider → 422 invalid_field \"IClient provider must be awsIam for HTTP IAM Role\n authentication.\"), must carry awsIam.roleArn (missing → 422 missing_required_field\n \"Expected field: awsIam.roleArn to be present.\"), and its role name must start with\n \"celigo-http-adaptor-\" (otherwise → 422 invalid_field_value). Omitting _iClientId\n altogether → 422 missing_required_field \"Expected field: _iClientId to be present.\"\n - |-\n An Azure Data Lake Storage Gen2 connection (assistant \"azuredatalakestoragegen2\", or any\n http.baseURI containing \"dfs.core.windows.net\") must reference an iClient with provider\n \"azureserviceprincipal\"; any other provider fails the save with 422 invalid_field\n \"IClient provider must be azureserviceprincipal for Azure Data Lake Storage Gen2\n connections.\"\n - |-\n The iClient must belong to the same account as the connection — an iClient id from\n another account fails with 422 invalid_ref \"The referenced IClient must belong to the\n same user.\" The one exception is the iClient a pre-built OAuth HTTP connector\n pre-configures (Celigo's published app — the Shopify Public App's, for one): the\n connection saves with that id from the connecting account even though\n `GET /v1/iclients/{_id}` on it is 404 there, so do not refuse a `public` Shopify\n connection on this rule.\n - |-\n On a Shopify connection keep `settings.appType` and `_iClientId` in step the way the\n form does — `public` with the connector's published iClient, `custom` with an\n account-owned iClient: the API saves either value of `settings.appType` beside either\n iClient (and any other string under `settings.appType`) — nothing server-side checks\n the pair, so the form's rule is the only guard. On an update never drop `_iClientId` from\n an `auth.type` `oauth` connection: 422 invalid_field_update \"Removing _iClientId is\n not allowed for oauth connections due to security reasons.\" — switch it to another\n iClient instead.\n _httpConnectorId:\n type: string\n format: objectId\n x-celigo-refModel: httpconnectors\n description: |-\n HTTP connector (pre-built application template) this connection is linked to. Linking\n lets exports and imports on the connection pick endpoints from the connector's catalog and\n drives the `assistant` form in the UI. The link is resolved server-side on create and on\n any update that changes `assistant` or a connector id, and the result overwrites\n `_httpConnectorId`, `_httpConnectorApiId` and `_httpConnectorVersionId`: an id that does\n not resolve to an accessible connector is dropped rather than rejected, and when the\n top-level `assistant` names an application with a legacy adaptor (the connector's\n `legacyId`, e.g. `shopify`) the connector resolved from that slug replaces the id you sent\n and a sent `_httpConnectorVersionId` is dropped. Read the response back to confirm the\n link took.\n examples:\n - 5d8f6a2b9c1e4f00112a3b4c\n x-celigo-ai-guidance:\n - |-\n To link an Azure Data Lake Storage Gen2 connection to its connector, send\n `_httpConnectorId` and `_httpConnectorVersionId` and omit the top-level `assistant`:\n with `assistant` set (`azuredatalakestoragegen2` or any other slug) the save answers\n 201/200 and stores neither id. Dropping `assistant` and re-sending both ids on a PUT\n restores the link.\n _httpConnectorApiId:\n type: string\n format: objectId\n x-celigo-refModel: httpconnectorapis\n description: |-\n API within the linked HTTP connector that this connection targets, for connectors that\n publish more than one API. Only meaningful together with `_httpConnectorId`; an id that is\n not one of that connector's APIs is dropped on save, not rejected.\n x-celigo-ai-guidance:\n - |-\n The connector catalog flags GraphQL APIs with `isGraphQL`. The API bound here is inherited\n by every export and import created on the connection — the step form's API type control\n is disabled once a connection is selected — so a connector's GraphQL editor requires a\n connection bound to its GraphQL API, not a per-step setting.\n examples:\n - 5d8f6a2b9c1e4f00112a3b4d\n _httpConnectorVersionId:\n type: string\n format: objectId\n description: |-\n Version entry of the linked HTTP connector (an item of the connector's `versions` array)\n whose endpoint definitions this connection uses. Only meaningful together with\n `_httpConnectorId`; an id that is not one of that connector's published versions is\n replaced by a published version of the connector on create and dropped on update, never\n rejected.\n examples:\n - 5d8f6a2b9c1e4f00112a3b4e\n isRest:\n type: boolean\n description: When true, this HTTP connection uses REST-style semantics (created from a REST connector template).\n useNewAuthFailSchema:\n type: boolean\n description: When true, the connection uses the newer authentication-failure detection schema for refresh/retry handling.\n if:\n properties:\n type:\n enum:\n - Amazon-SP-API\n - Amazon-Hybrid\n - vendor_central\n required:\n - type\n # Amazon types reject the POST with 422\n # (\"Expected field: marketplaceId/sellingRegion to be present\") unless both are set under unencrypted.\n # Else-if chain (no allOf): Amazon types require the unencrypted marketplace fields; otherwise\n # auth.type awsiam requires _iClientId (API-enforced: 422 missing_required_field, and the referenced\n # iClient is validated on save — see _iClientId). The auth.type credential matrix is a separate\n # if/then/else inside the `auth` object (above).\n then:\n required:\n - unencrypted\n properties:\n unencrypted:\n required:\n - marketplaceId\n - sellingRegion\n else:\n if:\n properties:\n auth:\n properties:\n type:\n const: awsiam\n required:\n - type\n required:\n - auth\n then:\n required:\n - _iClientId\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":55860,"content_sha256":"327dab9942d3480746413b579f41e17db9644330f0b885fc59d90d0cb7455070"},{"filename":"references/schemas/jdbc.yml","content":"JDBC:\n type: object\n description: |-\n Configuration for JDBC (Java Database Connectivity) connections. Used when the connection\n type is \"jdbc\". Provides access through Java JDBC drivers to databases not covered by the\n rdbms type — such as NetSuite SuiteAnalytics, Databricks, DB2, and Workday. The driver runs\n on a Celigo on-premise Agent, so most jdbc connections need a connection-level _agentId.\n x-celigo-ai-guidance:\n - The POST is rejected with 422 if type-specific required fields are missing (see the per-type conditional rules).\n - |-\n The agent and activedirectory types require a real connection-level _agentId: the POST fails with\n 422 \"The JDBC connection requires Agent. Expected field: _agentId to be present in the connection\n doc.\" A placeholder cannot be created without one, so the user should install a Celigo Agent first.\n Other types commonly run on an agent too, but only these two are validator-enforced (live-verified\n celigo-labs-2 2026-06-11).\n x-celigo-ui-override: >-\n Two activedirectory requireds mirror the connection form rather than the API: password and port\n (default 389). The API creates an activedirectory connection without them (it auto-defaults port\n to 389), but the form requires both, so they are encoded to mirror the form. The workday user and\n password requireds are NOT form overrides — they are enforced by the API itself (POST returns 422\n \"Expected field: user/password to be present\"). Per-type forms also require named entries inside\n jdbc.properties (netsuitejdbc AccountID + ServerDataSource; db2 AuthScheme; workday\n tenant/connectionType/authScheme; activedirectory LDAPVersion/BaseDN) — documented in prose since\n they live in the properties name/value array.\n required:\n - type\n properties:\n type:\n type: string\n enum:\n - agent\n - netsuitejdbc\n - databricks\n - oracle:thin\n - sqlserver\n - activedirectory\n - db2\n - workday\n x-enumDescriptions:\n agent: Generic JDBC driver deployed on a Celigo Agent (requires driverPath).\n netsuitejdbc: NetSuite SuiteAnalytics JDBC driver for reporting and analytics queries.\n databricks: Databricks SQL/Spark via JDBC.\n \"oracle:thin\": Oracle Database via the Oracle Thin JDBC driver.\n sqlserver: Microsoft SQL Server via the JTDS or Microsoft JDBC driver.\n activedirectory: SQL Server with Active Directory authentication.\n db2: IBM DB2 database via JDBC.\n workday: Workday via JDBC for report and data access.\n description: |-\n JDBC driver/connection type. Selects which JDBC driver is used and determines\n the required fields. Most JDBC connections require a Celigo on-premise Agent.\n examples: [\"netsuitejdbc\"]\n version:\n type: string\n description: JDBC driver version. Used for driver compatibility when multiple versions are available.\n examples: [\"19.3\"]\n host:\n type: string\n description: |\n Database server hostname or IP address.\n For NetSuite JDBC, use the SuiteAnalytics Connect hostname\n (e.g., \"account-id.connect.api.netsuite.com\").\n examples: [\"4241589.connect.api.netsuite.com\"]\n port:\n type: number\n description: Database server port number. Default varies by driver type.\n examples: [1708]\n x-celigo-ui-override: >-\n Required by the connection form for activedirectory (default 389) and db2. The API enforces it\n for db2 (POST 422 \"Expected field: port to be present\") but not for activedirectory, where the\n server auto-defaults it to 389. Encoded to mirror the form so builders produce connectable\n configurations.\n database:\n type: string\n description: |\n Database or catalog name. For Oracle, use the serviceName field instead.\n examples: [\"NetSuite2.com\"]\n user:\n type: string\n description: Database username for authentication.\n examples: [\"celigo_integration\"]\n password:\n type: string\n description: Database password (encrypted at rest).\n writeOnly: true\n examples: [\"my-db-password\"]\n x-celigo-ui-override: >-\n Required by the connection form for activedirectory connections; the API creates an\n activedirectory connection without it (form-derived, not API-enforced). For workday the\n password is enforced by the API itself, so it is encoded as an unconditional required on\n the workday branch rather than as a form override.\n serviceName:\n type: string\n description: |\n Oracle service name. Used instead of the database field for Oracle JDBC connections.\n This is the TNS service name or pluggable database (PDB) service name.\n examples: [\"oax5434857487_high\"]\n authType:\n type: string\n enum:\n - customjdbc\n - wallet\n x-enumDescriptions:\n customjdbc: Standard username and password authentication.\n wallet: Oracle Wallet authentication using an encrypted wallet file.\n description: |-\n Authentication method for the JDBC connection. Defaults to customjdbc (username/password).\n Use wallet for Oracle Wallet authentication with the wallet field.\n examples: [\"customjdbc\"]\n wallet:\n type: string\n description: |\n Oracle Wallet file contents (encrypted at rest).\n Required when authType is \"wallet\". Contains the auto-login wallet (cwallet.sso)\n with encrypted credentials for passwordless Oracle authentication.\n writeOnly: true\n driverPath:\n type: string\n description: |\n File path to the JDBC driver JAR on the Celigo Agent.\n Required when type is \"agent\" (generic JDBC).\n The driver must be deployed on the agent before creating the connection.\n examples: [\"/home/integration/jdbc-drivers\"]\n properties:\n type: array\n items:\n type: object\n properties:\n name:\n type: string\n description: JDBC connection property name (driver-specific).\n examples: [\"AccountID\"]\n value:\n type: string\n description: JDBC connection property value.\n examples: [\"4241589\"]\n description: |\n Additional JDBC connection properties as name/value pairs.\n These are passed directly to the JDBC driver as connection properties.\n Use for driver-specific settings like SSL mode, connection timeout,\n application name, etc.\n examples:\n - - name: AccountID\n value: \"4241589\"\n - name: ServerDataSource\n value: NetSuite2.com\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent database connections.\n JDBC connections often run through a single Agent, so keep this value\n conservative to avoid overwhelming the Agent or database.\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n examples: [5]\n targetConcurrencyLevel:\n type: integer\n description: |\n Target concurrency level for auto-scaling. The system adjusts the number of\n concurrent connections between 1 and this value based on performance feedback.\n examples: [10]\n minimum: 1\n maximum: 50\n default: 5\n # API requireds are enforced via 422 on connection POST.\n # The named entries that some types need inside `properties` are required by the validator but\n # documented in prose, not encoded, since only the presence of `properties` was verified:\n # netsuitejdbc → AccountID + ServerDataSource (422 missing_name until both present)\n # db2 → AuthScheme; workday → tenant/connectionType/authScheme; activedirectory → LDAPVersion/BaseDN\n # oracle:thin: host is required only for customjdbc (422 missing host); authType==wallet (NSAW/Oracle\n # Wallet) removes host and requires wallet+serviceName. Wallet auth nests inside the oracle:thin branch.\n # databricks needs only host (POST 201 with host alone).\n # workday `user`+`password` are API-enforced (POST 422 \"Expected field:\n # user/password to be present\"), so they're encoded as unconditional requireds on the workday branch.\n # Form-stricter-than-API additions (x-celigo-ui-override): the form requires `password` and `port`\n # for activedirectory — the API creates an activedirectory connection without them and\n # auto-defaults the port, but the form requires them, so they're encoded to mirror the form.\n # `agent` and `activedirectory` additionally require a connection-level `_agentId` (POST 422 \"The JDBC\n # connection requires Agent. Expected field: _agentId to be present\") — the\n # activedirectory `host`+`user`+`properties` requireds are likewise API-enforced. `_agentId` is\n # cross-level, so encoded in request.yml's jdbc branch (when jdbc.type is agent/activedirectory)\n # rather than this per-config schema.\n # Per-type conditional requireds mirror the connection form — nested if/else-if (no allOf).\n if:\n properties:\n type:\n const: db2\n required:\n - type\n then:\n required:\n - host\n - user\n - password\n - database\n - port\n - properties\n else:\n if:\n properties:\n type:\n const: 'oracle:thin'\n required:\n - type\n then:\n required:\n - user\n - password\n - authType\n # authType==wallet (NSAW/Oracle Wallet) removes host and requires wallet+serviceName;\n # customjdbc requires host (422 missing host for customjdbc; wallet POST passed field\n # validation without host).\n if:\n properties:\n authType:\n const: wallet\n required:\n - authType\n then:\n required:\n - wallet\n - serviceName\n else:\n required:\n - host\n else:\n if:\n properties:\n type:\n const: activedirectory\n required:\n - type\n then:\n required:\n - host\n - port\n - user\n - password\n - properties\n else:\n if:\n properties:\n type:\n const: netsuitejdbc\n required:\n - type\n then:\n required:\n - host\n - user\n - properties\n else:\n if:\n properties:\n type:\n const: agent\n required:\n - type\n then:\n required:\n - host\n - driverPath\n else:\n if:\n properties:\n type:\n const: workday\n required:\n - type\n then:\n required:\n - host\n - user\n - password\n - properties\n else:\n # databricks needs only host (POST 201 with host alone). Mirrors the generic\n # JDBC form, which marks only host required.\n if:\n properties:\n type:\n const: databricks\n required:\n - type\n then:\n required:\n - host\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":11441,"content_sha256":"9943f1788a97fcfb7f18bca55301919144532404e2e46bd398aeb3f32b822328"},{"filename":"references/schemas/jwt.yml","content":"JWT:\n type: object\n description: |-\n JWT Bearer authentication configuration. Used when auth.type is \"jwtbearer\" on HTTP\n connections. The connection builds a JWT from payload and headers, signs it using\n signatureMethod, and sends it as the bearer token. HMAC methods sign with secret;\n RSA/ECDSA/PSS methods sign with privateKey.\n properties:\n signatureMethod:\n type: string\n enum:\n - hmac-sha256\n - hmac-sha384\n - hmac-sha512\n - rsa-sha256\n - rsa-sha384\n - rsa-sha512\n - es256\n - es384\n - es512\n - ps256\n - ps384\n - ps512\n x-enumDescriptions:\n hmac-sha256: HMAC with SHA-256 (symmetric); signs with secret.\n hmac-sha384: HMAC with SHA-384 (symmetric); signs with secret.\n hmac-sha512: HMAC with SHA-512 (symmetric); signs with secret.\n rsa-sha256: RSA with SHA-256 (asymmetric); signs with privateKey.\n rsa-sha384: RSA with SHA-384 (asymmetric); signs with privateKey.\n rsa-sha512: RSA with SHA-512 (asymmetric); signs with privateKey.\n es256: ECDSA with P-256 and SHA-256 (asymmetric); signs with privateKey.\n es384: ECDSA with P-384 and SHA-384 (asymmetric); signs with privateKey.\n es512: ECDSA with P-521 and SHA-512 (asymmetric); signs with privateKey.\n ps256: RSASSA-PSS with SHA-256 (asymmetric); signs with privateKey.\n ps384: RSASSA-PSS with SHA-384 (asymmetric); signs with privateKey.\n ps512: RSASSA-PSS with SHA-512 (asymmetric); signs with privateKey.\n description: |-\n JWT signing method. Required when auth.type is \"jwtbearer\". HMAC methods require\n the secret field; RSA/ECDSA/PSS methods require the privateKey field.\n x-lowercase: true\n examples:\n - rsa-sha256\n payload:\n type: object\n additionalProperties: true\n x-celigo-agent:\n - handlebars\n description: |-\n JWT claims payload (the token body). Required and must be non-empty when auth.type\n is \"jwtbearer\". Keys are JWT claim names (e.g. iss, sub, aud, exp).\n examples:\n - {iss: my-service-account, sub: \"{sub}\", aud: https://api.example.com, exp: 3600}\n headers:\n type: object\n additionalProperties: true\n x-celigo-agent:\n - handlebars\n description: JWT header parameters merged into the generated token header (e.g. kid).\n examples:\n - {kid: my-key-id}\n secret:\n type: string\n writeOnly: true\n description: |-\n Shared secret for HMAC signature methods (hmac-sha256/hmac-sha512), encrypted at rest.\n Required when signatureMethod is an HMAC method.\n examples:\n - hmac-shared-s3cr3t-EXAMPLE\n isSecretBase64Encoded:\n type: boolean\n description: When true, the secret is base64-decoded before being used to sign.\n privateKey:\n type: string\n writeOnly: true\n description: |-\n PEM-encoded private key for RSA/ECDSA/PSS signature methods, encrypted at rest.\n Required for any rsa-*, es*, or ps* signature method.\n x-celigo-ai-guidance:\n - |-\n Private key in PEM format for RSA or ECDSA signing (encrypted at rest).\n REQUIRED when using an RSA (RS*) or ECDSA (ES*) algorithm.\n Not used with HMAC algorithms.\n token:\n type: string\n writeOnly: true\n description: |-\n Pre-generated static JWT to use instead of building one from payload (encrypted at rest).\n Use only when the API issues a long-lived JWT that does not need regeneration.\n examples:\n - eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.EXAMPLEpayload.EXAMPLEsignature\n # hmac-* signature methods require secret; rsa-*/es*/ps* require privateKey\n # (422 missing_required_field on POST). payload is always required\n # (empty {} is rejected) — noted in prose rather than `required` so vestigial jwt stubs\n # on non-jwtbearer connections still validate as responses.\n # Conditional requireds by signatureMethod — nested if/else-if (no allOf), stack-style.\n x-celigo-ai-guidance:\n - |-\n Pre-generated JWT token value (encrypted at rest).\n When set, this static token is used instead of generating one dynamically.\n Use only when the API provides a long-lived JWT that does not need to be regenerated.\n if:\n properties:\n signatureMethod:\n enum:\n - hmac-sha256\n - hmac-sha384\n - hmac-sha512\n required:\n - signatureMethod\n then:\n required:\n - secret\n else:\n if:\n properties:\n signatureMethod:\n enum:\n - rsa-sha256\n - rsa-sha384\n - rsa-sha512\n - es256\n - es384\n - es512\n - ps256\n - ps384\n - ps512\n required:\n - signatureMethod\n then:\n required:\n - privateKey\n x-celigo-ai-guidance:\n - |-\n Used when auth.type is \"jwtbearer\" on HTTP connections. The system generates\n a signed JWT and uses it as a bearer token for API authentication.\n\n ## SIGNING METHODS\n - HMAC (HS256/HS384/HS512): Symmetric signing using a shared secret.\n Requires the secret field.\n - RSA (RS256/RS384/RS512): Asymmetric signing using an RSA private key.\n Requires the privateKey field.\n - ECDSA (ES256/ES384/ES512): Asymmetric signing using an elliptic curve private key.\n Requires the privateKey field.\n\n ## REQUIRED FIELDS\n - algorithm (signing algorithm)\n - secret (for HMAC algorithms) OR privateKey (for RSA/ECDSA algorithms)\n - At least one claim (issuer, subject, audience, or customClaims)\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":5722,"content_sha256":"a525db0ed6695d286fef78ccf507b462fe413b3b4f6c949106f54eb0f4989f1e"},{"filename":"references/schemas/mcp.yml","content":"MCP:\n type: object\n description: |-\n Configuration for MCP (Model Context Protocol) connections. Used when the connection type\n is \"mcp\". Lets Celigo call tools exposed by an external MCP server over HTTP. Authentication\n goes through the http sub-object, which reuses the HTTP auth config but accepts only the\n token, oauth, and custom auth types.\n # Unlike http, an MCP connection requires an\n # authentication type (422 \"Authentication type is required\"), so http and http.auth.type are\n # required, and the type is validated to token/oauth/custom (422 \"Authentication type basic is\n # invalid\" — enum narrowed below, not inherited from http.yml). token additionally requires\n # http.auth.token.token (a connection with a static token POSTs 201; without one the API instead\n # demands token.refreshMethod for a refresh flow). oauth/custom have no API-enforced credential\n # requireds (both POST 201 with only the type); http._iClientId is form-derived — flagged on the\n # field. Nested if/then/else inside the http object, no allOf.\n required:\n - serverURL\n - http\n properties:\n protocol:\n type: string\n enum: [http]\n x-enumDescriptions:\n http: Communicate with the MCP server over HTTP.\n default: http\n readOnly: true\n description: |\n Transport protocol for communicating with the MCP server.\n Currently only \"http\" is supported; the server sets this automatically and ignores other values.\n serverURL:\n type: string\n format: uri\n x-celigo-agent:\n - handlebars\n description: |-\n MCP server endpoint URL. Must be a valid absolute URL\n (e.g. \"https://mcp-server.example.com/mcp\").\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n examples:\n - https://mcp-server.example.com/mcp\n x-celigo-ai-guidance:\n - |-\n MCP server endpoint URL. REQUIRED.\n Must be a valid absolute URL (e.g., \"https://mcp-server.example.com/mcp\").\n The system validates this as a proper URL.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data\n sent to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n timeout:\n type: number\n default: 600000\n description: |\n Request timeout in milliseconds for MCP tool invocations.\n If the MCP server does not respond within this time, the request fails.\n Defaults to 600000 (10 minutes) when omitted.\n examples:\n - 600000\n allowedTools:\n type: array\n description: |\n Optional allowlist of MCP tool names that this connection may invoke.\n When set, only tools in this list can be called. When omitted or empty,\n all tools exposed by the MCP server are available.\n items:\n type: string\n examples:\n - search_records\n examples:\n - [search_records, create_record]\n http:\n type: object\n required:\n - auth\n description: |\n HTTP transport configuration for the MCP connection, including authentication and headers.\n properties:\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n description: |\n Reference to an OAuth iClient for OAuth-based MCP authentication.\n Required when http.auth.type is \"oauth\".\n examples:\n - 66a1b2c3d4e5f60718293a4b\n x-celigo-ui-override: >-\n Required by the connection form for oauth auth; the OAuth authorization is completed\n after the connection is created.\n auth:\n type: object\n required:\n - type\n description: |\n Authentication configuration for the MCP connection. The auth.type field selects the\n strategy. MCP supports only token, oauth, and custom — other HTTP auth types\n (basic, wsse, cookie, jwt, etc.) are rejected with a 422.\n properties:\n type:\n type: string\n enum:\n - token\n - oauth\n - custom\n x-enumDescriptions:\n token: API key or bearer token; set auth.token.token (sent via header, URL parameter, or request body).\n oauth: OAuth 2.0; reference an OAuth iClient via http._iClientId and complete the authorization after the connection is created.\n custom: No built-in auth; place credentials in http.headers or the http.encrypted / http.unencrypted custom fields.\n description: |-\n Authentication method for the MCP server. Determines which auth sub-fields apply.\n x-lowercase: true\n examples:\n - token\n token:\n $ref: './http.yml#/HTTP/properties/auth/properties/token'\n oauth:\n $ref: './oauth.yml#/OAuth'\n headers:\n type: array\n description: |\n Default HTTP headers included in every request to the MCP server.\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name.\n examples:\n - X-API-Key\n value:\n type: string\n x-celigo-agent:\n - handlebars\n description: Header value. Supports handlebars expressions for dynamic values.\n examples:\n - '{{{connection.http.encrypted.apiKey}}}'\n required: [name, value]\n unencrypted:\n type: object\n description: Unencrypted custom fields for non-sensitive MCP configuration.\n encrypted:\n type:\n - object\n - string\n description: |-\n Encrypted custom fields for sensitive MCP configuration. Sent as an object;\n returned as the masked string `\"******\"` on responses.\n # auth.type credential rule — else-if (no allOf).\n # token -> auth.token.token; oauth -> _iClientId (form-derived); custom -> no extra requireds.\n if:\n properties:\n auth:\n properties:\n type:\n const: token\n required:\n - type\n required:\n - auth\n then:\n properties:\n auth:\n required:\n - token\n properties:\n token:\n required:\n - token\n else:\n if:\n properties:\n auth:\n properties:\n type:\n const: oauth\n required:\n - type\n required:\n - auth\n then:\n required:\n - _iClientId\n x-celigo-ai-guidance:\n - |-\n The auth.type MUST be one of: \"token\", \"oauth\", or \"custom\".\n Other auth types (basic, cookie, jwt, etc.) are not supported for MCP connections.\n x-celigo-ai-guidance:\n - |-\n MCP connections enable Celigo to call tools exposed by an external MCP server\n over HTTP. The MCP server provides a set of callable tools that can be invoked\n during flow execution.\n\n ## REQUIRED FIELDS\n - serverURL (the MCP server's HTTP endpoint)\n - http.auth.type (must be one of: \"token\", \"oauth\", or \"custom\")\n\n ## AUTHENTICATION\n MCP connections authenticate via the http sub-object, which reuses the same\n auth configuration as HTTP connections but with a restricted set of auth types.\n Only \"token\", \"oauth\", and \"custom\" are valid for MCP connections.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":7865,"content_sha256":"1e8c209ba02dc429cc24d7bfbfbae540f38b39fa2f339d5e765944309776b818"},{"filename":"references/schemas/mongodb.yml","content":"MongoDB:\n type: object\n description: |-\n Configuration for MongoDB connections. Used when the connection type is \"mongodb\". Supports\n standalone instances, replica sets, and MongoDB Atlas clusters. For a replica set, list all\n member addresses in host and set replicaSet to the set name; authSource selects the\n authentication database when it differs from the target database.\n x-celigo-ai-guidance:\n - |-\n A minimal connectable config needs host, username, and password — the POST is rejected with\n 422 \"Expected field: \u003cfield> to be present\" if any of the three is missing. database is not\n required; when omitted, set it per operation instead.\n - |-\n For an on-premise MongoDB instance, set the connection-level _agentId (the form's \"On-premise\"\n mode) so traffic routes through a Celigo Agent. Cloud-reachable instances (including Atlas)\n need no agent.\n - |-\n ## AUTHENTICATION\n Username and password are optional — only required when the MongoDB server has\n authentication enabled (which is recommended for production).\n Use authSource to specify the authentication database if it differs from the target database.\n\n ## REPLICA SETS\n For replica sets, provide all member hostnames in the host array and set\n the replicaSet field to the replica set name.\n x-celigo-ui-override: >-\n host, username, and password are required by the connection form (and the API). database is\n intentionally optional — the form does not require it and the API accepts a connection without\n it (live-verified). Encoded to mirror the form so builders produce connectable configurations.\n required:\n - host\n - username\n - password\n properties:\n host:\n type: array\n minItems: 1\n items:\n type: string\n description: |\n MongoDB server addresses. An array of one or more host:port strings.\n\n - Standalone: [\"mongodb.example.com:27017\"]\n - Replica set: [\"rs1.example.com:27017\", \"rs2.example.com:27017\", \"rs3.example.com:27017\"]\n - MongoDB Atlas: [\"cluster0-shard-00-00.abc.mongodb.net:27017\", ...]\n\n Include the port number with each host. Default MongoDB port is 27017.\n examples:\n - [\"mongodb.example.com:27017\"]\n - [\"rs1.example.com:27017\", \"rs2.example.com:27017\", \"rs3.example.com:27017\"]\n database:\n type: string\n description: |\n Target MongoDB database name.\n All operations (reads/writes) target collections within this database.\n Optional on the connection — when omitted, set the database per operation instead.\n examples: [\"orders\"]\n username:\n type: string\n description: MongoDB username for authentication.\n examples: [\"mongo_app_user\"]\n x-celigo-ai-guidance:\n - |-\n MongoDB username for authentication.\n Required when the MongoDB server has authentication enabled.\n password:\n type: string\n writeOnly: true\n description: MongoDB password. Write-only — accepted on create/update and returned masked as `\"******\"`.\n examples: [\"s3cr3t-mongo-pw\"]\n replicaSet:\n type: string\n description: |\n MongoDB replica set name. Set this when connecting to a replica set so the driver can\n discover all members and handle failover. For MongoDB Atlas, this is typically\n \"atlas-xxxxxx-shard-0\".\n examples: [\"rs0\"]\n x-celigo-ai-guidance:\n - |-\n MongoDB replica set name. Required when connecting to a replica set.\n The driver uses this to discover all replica set members and handle failover.\n For MongoDB Atlas, this is typically \"atlas-xxxxxx-shard-0\".\n ssl:\n type: boolean\n description: |\n When true, connects to MongoDB over TLS/SSL.\n Required for MongoDB Atlas and recommended for all production deployments.\n default: false\n authSource:\n type: string\n description: |\n MongoDB authentication database — the database where the user credentials are stored.\n Defaults to the value of the database field. Set to \"admin\" if the user was created\n in the admin database (common for shared MongoDB deployments and Atlas).\n examples: [\"admin\"]\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent MongoDB operations.\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |\n Target concurrency level for auto-scaling. The system adjusts concurrency\n between 1 and this value based on rate limit feedback.\n\n Only relevant when autoRecoverRateLimitErrors is enabled on the connection.\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ui-override: >-\n Required by the connection form only when autoRecoverRateLimitErrors (a connection-root\n field) is enabled. Not gated with if/then/else here because that field is a sibling of the\n mongodb object, not a property of it — a nested conditional could not reference it. The API\n auto-populates this (defaults to 5 on create) rather than rejecting its absence, so it is a\n form-mirroring rule, not an API constraint. Matches how http/rdbms document the field.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":5432,"content_sha256":"5f8f0a65feebf72af41f0ffbaff489e4c0e463d8f0e75f86c1f6a0356102fcc7"},{"filename":"references/schemas/netsuite.yml","content":"NetSuite:\n type: object\n description: |-\n Configuration for NetSuite ERP connections. Used when the connection type is \"netsuite\".\n The authType field selects the authentication method; token-based authentication (TBA) is\n recommended for production.\n required:\n - authType\n x-celigo-ai-guidance:\n - |-\n For placeholder/dummy NetSuite connections, use authType \"token-auto\" with just the account id —\n integrator.io manages the OAuth client wiring on the backend, so no placeholder tokens are needed.\n x-celigo-ui-override: >-\n authType is required by the connection form (the API itself accepts a connection without it). The\n per-auth-type requireds likewise mirror the form: basic requires email and password; token\n requires account, environment, tokenId, and tokenSecret; token-auto requires account. The API\n enforces none of these (each was live-verified to POST 201 when omitted); they are encoded in the\n connection request schema's type=netsuite branch (not in this file, which jdbc connections also\n embed for NetSuite JDBC auth) so builders produce connectable connections.\n properties:\n authType:\n type: string\n examples: [\"token-auto\"]\n enum:\n - basic\n - token\n - token-auto\n x-celigo-deprecated-enum-values:\n # `basic` is kept in source (existing connections may still report it) but stripped from\n # the published bundle: new basic connections are rejected by the API (TBA-only WSDLs).\n - basic\n x-enumDescriptions:\n basic: Legacy email and password authentication (not recommended for new connections).\n token: Manual Token-Based Authentication (TBA) using tokenId and tokenSecret from a NetSuite integration record.\n token-auto: Automatic token management via Celigo's iClient; requires only the NetSuite account ID.\n description: |-\n Authentication method for the NetSuite connection. token-auto delegates the token\n lifecycle to an iClient; token uses a manually-supplied tokenId/tokenSecret pair.\n x-celigo-ai-guidance:\n - |-\n Default to \"token-auto\" for new connections, including placeholders (only the account id is needed).\n Use \"token\" when the user supplies their own tokenId/tokenSecret. Do not create \"basic\" connections:\n the API rejects them with 422 \"netsuite_wsdl_tba_mandatory\" because the available WSDL versions\n require Token-Based Authentication.\n x-lowercase: true\n account:\n type: string\n examples: [\"TSTDRV1234567\"]\n description: |-\n NetSuite account ID (automatically uppercased), required for token and token-auto authentication.\n Found in NetSuite under Setup > Company > Company Information. Non-production accounts\n carry an environment suffix (e.g. `123456_SB1`); production and beta use the bare id.\n x-uppercase: true\n environment:\n type: string\n examples: [\"production\"]\n enum:\n - production\n - sandbox\n - sandbox2.0\n - beta\n x-enumDescriptions:\n production: Connect to the live production NetSuite instance.\n sandbox: Connect to a legacy NetSuite sandbox account.\n sandbox2.0: Connect to a NetSuite SuiteCloud (SB2.0) sandbox account.\n beta: Connect to the NetSuite beta/release-preview environment.\n description: |-\n NetSuite environment to connect to. Defaults to production when not specified.\n tokenId:\n type: string\n examples: [\"c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2\"]\n description: |\n NetSuite TBA token ID (encrypted at rest). Required when authType is \"token\".\n\n Generated in NetSuite under Setup > Users/Roles > Access Tokens.\n Must be paired with the corresponding tokenSecret.\n x-celigo-ai-guidance:\n - Not needed when authType is \"token-auto\" — integrator.io manages the token wiring in that mode.\n writeOnly: true\n tokenSecret:\n type: string\n examples: [\"3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a\"]\n description: |\n NetSuite TBA token secret (encrypted at rest). Required when authType is \"token\".\n\n Generated alongside the tokenId in NetSuite. Treat as a sensitive credential.\n x-celigo-ai-guidance:\n - Not needed when authType is \"token-auto\".\n writeOnly: true\n entityId:\n type: string\n examples: [\"1234\"]\n description: NetSuite entity/user ID associated with the token.\n tokenName:\n type: string\n examples: [\"Celigo integration token\"]\n description: Human-readable name of the NetSuite access token for identification purposes.\n roleId:\n type: string\n examples: [\"3\"]\n description: |\n NetSuite role ID that determines the permissions for this connection.\n\n The role controls which records, fields, and operations are accessible.\n Must match the role associated with the access token in NetSuite.\n email:\n type: string\n deprecated: true\n description: |\n NetSuite user email address. Required when authType is \"basic\".\n Used as the login credential for basic (email/password) authentication.\n format: email\n password:\n type: string\n deprecated: true\n description: NetSuite user password (encrypted at rest). Required when authType is \"basic\".\n writeOnly: true\n requestLevelCredentials:\n type: boolean\n default: false\n description: |\n When true, authentication credentials are sent with each individual API request\n rather than maintaining a persistent session. The connection form sets this to true\n for token (manual TBA) authentication.\n useSsoLogin:\n type: boolean\n readOnly: true\n deprecated: true\n description: |-\n Legacy single-sign-on login flag for the deprecated basic (email/password) auth flow. Not exposed\n by the current connection form and not settable via the API (writes are silently dropped); retained\n for the existing connections that carry it. New connections use token-based authentication instead.\n dataCenterURLs:\n type: object\n description: |\n NetSuite data center URLs for the account, auto-discovered from the account ID.\n These are populated by the server after a successful connection.\n readOnly: true\n properties:\n restDomain:\n type: string\n examples: [\"https://1234567.restlets.api.netsuite.com\"]\n description: Base URL for the account's RESTlet and REST API endpoints.\n webservicesDomain:\n type: string\n examples: [\"https://1234567.suitetalk.api.netsuite.com\"]\n description: Base URL for the account's SuiteTalk (SOAP) web services endpoints.\n systemDomain:\n type: string\n examples: [\"https://1234567.app.netsuite.com\"]\n description: Base URL for the account's NetSuite UI/system endpoints.\n x-celigo-ai-guidance:\n - |-\n NetSuite data center URL overrides. Normally auto-discovered from the account ID.\n Only set this to override the default data center routing.\n accountName:\n type: string\n examples: [\"My Company, Inc.\"]\n description: Human-readable NetSuite account name (display purposes only).\n roleName:\n type: string\n examples: [\"Administrator\"]\n description: Human-readable name of the NetSuite role (display purposes only).\n wsdlVersion:\n type: string\n examples: [\"latest\"]\n description: |-\n SuiteTalk Web Services WSDL version. The API stores only `latest` or `next`; any other value sent\n on create or update is normalized to one of these (the connection form's \"2025.1\" maps to `latest`\n and \"2023.1\" maps to `next`; unrecognized version strings fall back to `latest`). Defaults to\n `latest`, which requires Token-Based Authentication.\n enum:\n - latest\n - next\n x-enumDescriptions:\n latest: Current default WSDL release. Shown in the connection form as \"2025.1\".\n next: Alternate WSDL release. Shown in the connection form as \"2023.1\".\n default: latest\n applicationId:\n type: string\n examples: [\"E3CA9D5B-1C2D-3E4F-5A6B-7C8D9E0F1A2B\"]\n description: |\n NetSuite application ID from the integration record.\n Required for some authentication configurations to identify the calling application.\n concurrencyLevelRESTlet:\n type: number\n readOnly: true\n deprecated: true\n description: |-\n Deprecated per-endpoint cap on concurrent NetSuite RESTlet requests, superseded by the unified\n `concurrencyLevel`. Server-reported only — values sent on create or update are silently dropped\n (live-verified); retained for existing connections.\n x-celigo-ai-guidance:\n - |-\n Maximum concurrent requests to NetSuite RESTlet endpoints.\n NetSuite enforces governance limits on concurrent RESTlet requests per account.\n Keep this low to avoid SuiteScript governance errors.\n concurrencyLevelWebServices:\n type: number\n readOnly: true\n deprecated: true\n description: |-\n Deprecated per-endpoint cap on concurrent NetSuite SuiteTalk Web Services (SOAP) requests, superseded\n by the unified `concurrencyLevel`. Server-reported only — values sent on create or update are\n silently dropped (live-verified); retained for existing connections.\n x-celigo-ai-guidance:\n - |-\n Maximum concurrent requests to NetSuite SuiteTalk Web Services (SOAP API).\n NetSuite enforces concurrency limits per account — exceeding them causes\n \"Only one request may be made against a session at a time\" errors.\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of requests this connection sends to NetSuite in parallel, across SOAP,\n REST and RESTlet calls. Send no more than the integrator.io license ceiling (25 standard,\n 50 with an Environments license). NetSuite separately enforces one\n concurrency limit per NetSuite account that every caller of its SOAP, REST and RESTlet\n APIs shares — all integrator.io connections to that account and every other client\n calling those APIs from outside integrator.io (other integrations, third-party tools).\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ai-guidance:\n - |-\n Before raising this connection's ceiling — `targetConcurrencyLevel` while\n `autoRecoverRateLimitErrors` is on (the default; a PUT of `concurrencyLevel` then\n changes nothing), `concurrencyLevel` only while it is off — total the ceilings of every\n connection that targets the same NetSuite `account` and `environment` (a connection\n that borrows counts under its parent) and keep that total, plus whatever calls the\n account's APIs from outside integrator.io, within the NetSuite account limit; a value\n that fits this connection alone can still push the whole account over.\n - |-\n The NetSuite limit is the service-tier base (Standard 5, Premium 15, Enterprise and\n Ultimate 20; legacy tiers 5–20) plus 10 per SuiteCloud Plus license; a sandbox matches\n its production account. Development and partner accounts are fixed at 5 and do not\n scale with licenses. NetSuite shows the limit at Setup > Integration > Integration\n Management > Integration Governance; integrator.io cannot read it — ask for the number\n rather than assuming headroom.\n - |-\n Over the limit, NetSuite rejects requests from every caller of that account at once,\n not only this connection's — SOAP: `ExceededConcurrentRequestLimitFault` /\n `WS_REQUEST_BLOCKED`; REST web services: HTTP 429; RESTlets: HTTP 400\n `SSS_REQUEST_LIMIT_EXCEEDED`. To run several connections against one NetSuite account,\n put the limit on one parent and point the others at it with\n `_borrowConcurrencyFromConnectionId`; otherwise raise in small steps.\n targetConcurrencyLevel:\n type: integer\n description: |-\n Target concurrency level for auto-scaling. The system adjusts concurrency\n between 1 and this value based on rate limit and governance feedback.\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ai-guidance:\n - |-\n With `autoRecoverRateLimitErrors` on, this is the level the connection climbs back to\n after a recovery, so it — not `concurrencyLevel` — is the value that must fit the shared\n NetSuite account budget described on `concurrencyLevel`.\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n examples: [\"66a1b2c3d4e5f60718293a4b\"]\n description: ID of the iClient used for token-based authentication.\n # The per-authType conditional requireds live in request.yml's type=netsuite branch (not here):\n # jdbc connections embed this same subdoc for NetSuite JDBC auth, and the connection-form rules\n # (e.g. token-auto requiring account) do not apply there. The form's tokenAccount/tokenEnvironment\n # map to account/environment on save.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":13433,"content_sha256":"189ad00792f30f88984ed03ec23ca13f2d8aa329030da8381e5215feb15e4c75"},{"filename":"references/schemas/oauth.yml","content":"OAuth:\n type: object\n description: |-\n OAuth 2.0 and OAuth 1.0a authentication configuration.\n Used as a sub-object within HTTP and REST connection auth configurations.\n The grantType field selects the OAuth 2.0 flow; for legacy OAuth 1.0a APIs, use the oauth1 sub-object.\n properties:\n type:\n type: string\n enum:\n - custom\n - assistant\n x-enumDescriptions:\n custom: Fully user-configured OAuth settings.\n assistant: Pre-configured OAuth settings via an application assistant connector.\n description: |-\n OAuth configuration mode. Controls whether settings are user-configured or\n pre-populated by an application assistant connector.\n examples:\n - custom\n grantType:\n type: string\n enum:\n - authorizecode\n - clientcredentials\n - password\n x-enumDescriptions:\n authorizecode: Authorization Code flow requiring user consent via browser redirect.\n clientcredentials: Client Credentials flow for server-to-server authentication without user involvement.\n password: Resource Owner Password Credentials flow exchanging username and password for tokens.\n description: |-\n OAuth 2.0 grant type that determines the authentication flow.\n Use authorizecode for user-context integrations, clientcredentials for\n server-to-server, and password only when the API does not support other flows.\n default: authorizecode\n x-lowercase: true\n examples:\n - authorizecode\n authURI:\n type: string\n description: |\n OAuth 2.0 authorization endpoint URL.\n Required for \"authorizecode\" grant type. The user is redirected to this URL\n to authorize the application.\n Handlebars expressions are supported for tenant-specific endpoints — e.g.\n \"https://{{{connection.settings.storeName}}}.myshopify.com/admin/oauth/authorize\".\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n examples:\n - https://login.example.com/oauth2/authorize\n tokenURI:\n type: string\n description: |\n OAuth 2.0 token endpoint URL.\n Required for \"authorizecode\", \"clientcredentials\", and \"password\" grant types.\n The system exchanges credentials or authorization codes for access tokens at this URL.\n Handlebars expressions are supported for tenant-specific endpoints.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n examples:\n - https://login.example.com/oauth2/token\n skipOauthValidations:\n type: boolean\n description: |\n When true, skips Celigo's built-in OAuth configuration validation.\n Use when the API has non-standard OAuth requirements that conflict with validation rules.\n default: false\n scope:\n type: array\n items:\n type: string\n description: |\n OAuth scopes to request during authorization. Controls the level of API access.\n Scope values are API-specific (e.g., \"read\", \"write\", \"admin\").\n examples:\n - [read, write]\n scopeDelimiter:\n type: string\n description: |\n Delimiter between multiple scope values. Defaults to a space (\" \") per the\n OAuth 2.0 spec. Some APIs use commas or other delimiters.\n default: \" \"\n clientId:\n type: string\n description: |\n OAuth client ID (application ID) registered with the API provider. An `http`\n connection takes the app from a `custom_oauth2` iClient referenced by `http._iClientId`\n (an `mcp` connection from `mcp.http._iClientId`) and doesn't store this field: a create\n that sends `clientId` and `clientSecret` here answers 201 without either (and stores\n `useIClientFields: true` unless `false` is sent).\n examples:\n - 0oa1b2c3d4EXAMPLE5\n clientSecret:\n type: string\n description: |\n OAuth client secret (encrypted at rest). Not stored on an `http` connection: the secret\n belongs on the iClient (see `clientId`).\n writeOnly: true\n examples:\n - cs_abc123EXAMPLE456secret\n username:\n type: string\n description: |\n Resource owner username. Required when grantType is \"password\".\n examples:\n - svc_account\n password:\n type: string\n description: |\n Resource owner password (encrypted at rest). Required when grantType is \"password\".\n writeOnly: true\n examples:\n - s3cr3t-p4ssw0rd\n clientCredentialsLocation:\n type: string\n enum:\n - basicauthheader\n - body\n x-enumDescriptions:\n basicauthheader: Send client credentials as an HTTP Basic Auth header (recommended).\n body: Send client credentials as form parameters in the request body.\n description: |-\n Where to send client credentials in token requests. Defaults to basicauthheader\n (HTTP Basic Auth), which is recommended by the OAuth spec. Use body when\n the API does not support Basic Auth for client credentials.\n default: basicauthheader\n x-lowercase: true\n examples:\n - basicauthheader\n accessTokenPath:\n type: string\n description: |\n JSON path to extract the access token from the token endpoint response.\n Defaults to \"access_token\" per the OAuth 2.0 spec.\n Change only if the API returns the token at a non-standard path.\n examples:\n - data.access_token\n accessTokenHeaders:\n type: array\n description: |\n Additional HTTP headers to include in token endpoint requests.\n Use for APIs that require custom headers beyond the standard OAuth parameters.\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name to send with the token request.\n examples:\n - X-Tenant-ID\n value:\n type: string\n description: Header value to send with the token request.\n examples:\n - acme-prod\n accessTokenBody:\n type: string\n description: |\n Additional body content to include in token endpoint requests.\n Appended to the standard OAuth parameters.\n examples:\n - audience=https://api.example.com\n oauth2RedirectUrl:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n OAuth 2.0 redirect URI (callback URL) registered with the API provider.\n Must exactly match the redirect URI configured in the OAuth application registration.\n examples:\n - https://integrator.io/connection/oauth2callback\n useIClientFields:\n type: boolean\n description: |\n When true, uses iClient-managed OAuth credentials (clientId/clientSecret)\n instead of the values in this configuration. The iClient is the connection's\n `_iClientId` — on an HTTP connection `http._iClientId`, beside `auth`, not inside it —\n and it also supplies the grant type and the authorization and token endpoints, so a\n create needs only `auth.type: \"oauth\"`, `auth.oauth.useIClientFields: true` and the\n iClient id. The connection holds no tokens until a person completes the authorization\n in a browser.\n oauth1:\n type: object\n description: |-\n OAuth 1.0a configuration for legacy APIs that use the older OAuth protocol.\n Always needs consumerKey and accessToken; HMAC signature methods also need\n consumerSecret and tokenSecret, while RSA methods need consumerPrivateKey.\n properties:\n consumerKey:\n type: string\n description: |\n OAuth 1.0a consumer key (API key).\n Identifies the application making the request.\n examples:\n - dpf43f3p2l4k3l03\n consumerSecret:\n type: string\n description: |\n OAuth 1.0a consumer secret (encrypted at rest).\n Required for HMAC and PLAINTEXT signature methods.\n writeOnly: true\n examples:\n - kd94hf93k423kf44EXAMPLE\n accessToken:\n type: string\n description: |\n OAuth 1.0a access token (encrypted at rest).\n Represents the user's authorization for the application to access their data.\n writeOnly: true\n examples:\n - nnch734d00sl2jdkEXAMPLE\n tokenSecret:\n type: string\n description: |\n OAuth 1.0a token secret (encrypted at rest).\n Required for HMAC and PLAINTEXT signature methods.\n writeOnly: true\n examples:\n - pfkkdhi9sl3r4s00EXAMPLE\n signatureMethod:\n type: string\n enum:\n - hmac-sha1\n - hmac-sha256\n - hmac-sha512\n - rsa-sha1\n - rsa-sha256\n - rsa-sha512\n - plaintext\n x-enumDescriptions:\n hmac-sha1: HMAC signing with SHA-1 (most widely supported, legacy).\n hmac-sha256: HMAC signing with SHA-256 for improved security.\n hmac-sha512: HMAC signing with SHA-512 (strongest HMAC variant).\n rsa-sha1: RSA signing with SHA-1 (legacy).\n rsa-sha256: RSA signing with SHA-256 for improved security.\n rsa-sha512: RSA signing with SHA-512 (strongest RSA variant).\n plaintext: No cryptographic signing, only for testing over HTTPS.\n description: |-\n OAuth 1.0a request signing method. HMAC methods require consumerSecret and\n tokenSecret; RSA methods require consumerPrivateKey. PLAINTEXT offers no\n cryptographic signing and should only be used for testing over HTTPS.\n x-lowercase: true\n examples:\n - hmac-sha1\n consumerPrivateKey:\n type: string\n description: |\n RSA private key for OAuth 1.0a RSA signature methods (encrypted at rest).\n Required when signatureMethod is RSA-SHA1, RSA-SHA256, or RSA-SHA512.\n writeOnly: true\n realm:\n type: string\n x-celigo-agent:\n - handlebars\n description: |\n OAuth realm value included in the Authorization header.\n Some APIs require this to identify the authentication domain.\n examples:\n - https://api.example.com\n x-celigo-ai-guidance:\n - |-\n ## REQUIRED FIELDS\n - consumerKey (always required)\n - accessToken (always required)\n - For HMAC methods: consumerSecret and tokenSecret\n - For RSA methods: consumerPrivateKey\n pkceCodeVerifier:\n type: string\n description: |\n PKCE (Proof Key for Code Exchange) code verifier for enhanced OAuth 2.0 security.\n Managed internally by the system during authorization code flows.\n writeOnly: true\n examples:\n - dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\n # Enforced via 422 on connection POST:\n # authorizecode requires authURI; clientcredentials requires tokenURI.\n # Conditional requireds by grantType — nested if/else-if (no allOf), stack-style.\n if:\n properties:\n grantType:\n const: authorizecode\n required:\n - grantType\n then:\n required:\n - authURI\n - tokenURI\n else:\n if:\n properties:\n grantType:\n const: clientcredentials\n required:\n - grantType\n then:\n required:\n - tokenURI\n else:\n if:\n properties:\n grantType:\n const: password\n required:\n - grantType\n then:\n required:\n - tokenURI\n - username\n - password\n x-celigo-ai-guidance:\n - |-\n ## OAUTH 2.0 GRANT TYPES\n - \"authorizecode\" — Authorization Code flow (browser-based user consent).\n Requires authURI, tokenURI, and user authorization via browser.\n - \"clientcredentials\" — Client Credentials flow (server-to-server, no user).\n Requires tokenURI.\n - \"password\" — Resource Owner Password flow (username/password exchange).\n Requires tokenURI, username, password.\n - On an `http` connection the client ID and secret are never stored here: a\n `custom_oauth2` iClient referenced by `http._iClientId` supplies them.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":12608,"content_sha256":"b8740e5877f9ea3e753dd19dd4a3956a54fd4dd310bc29fce33a6fa931264297"},{"filename":"references/schemas/pgp.yml","content":"PGP:\n type: object\n description: |-\n PGP encryption settings for file-based connections (ftp, s3, and similar). When set, files are\n PGP-encrypted before upload and/or decrypted after download. Supply at least one of `publicKey`\n (to encrypt outbound files) or `privateKey` (to decrypt inbound files); set `passphrase` whenever\n `privateKey` is provided.\n properties:\n publicKey:\n type: string\n description: |-\n ASCII-armored PGP public key used to encrypt outbound files before upload.\n Set this when the connection sends encrypted files; omit it for decrypt-only connections.\n x-celigo-ai-guidance:\n - |-\n Public key for JWT verification. Optional — used when the API requires\n the public key to be registered for signature verification.\n privateKey:\n type: string\n writeOnly: true\n description: |-\n ASCII-armored PGP private key used to decrypt inbound files after download (encrypted at rest;\n returned masked as `\"******\"`). Set this when the connection receives encrypted files.\n passphrase:\n type: string\n writeOnly: true\n description: Passphrase that unlocks `privateKey` (encrypted at rest; returned masked as `\"******\"`). Set this whenever `privateKey` is provided.\n compressionAlgorithm:\n type: string\n enum:\n - zip\n - zlib\n x-enumDescriptions:\n zip: ZIP compression — the most widely compatible option.\n zlib: zlib/DEFLATE compression.\n description: Compression applied to the message payload before PGP encryption. Match the algorithm the recipient expects; leave unset to use the server default.\n asciiArmored:\n type: boolean\n default: true\n description: When true, produces ASCII-armored (text) PGP output. Set to false only when the recipient requires binary PGP output.\n # Form rule (GitBook ignores if/then; downstream consumers get form-accurate validation):\n # supplying a private key also requires its passphrase.\n if:\n required: [privateKey]\n then:\n required: [passphrase]\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":2100,"content_sha256":"3e3c17b4985671e8b24f0e0b9ea1c912af7c8307c2c80832cf3def171c22f567"},{"filename":"references/schemas/rdbms.yml","content":"RDBMS:\n type: object\n description: |-\n Configuration for relational database connections. Used when the connection type is \"rdbms\".\n The type field selects the database system, which determines the SQL dialect, connection driver,\n default port, and which additional sub-fields are required.\n x-celigo-ai-guidance:\n - The POST is rejected with 422 if type-specific required fields are missing (see the per-type conditional rules).\n - |-\n For Oracle, a placeholder connection cannot be created without a real connection-level _agentId\n (validator error agent_mode_only) — direct the user to install a Celigo Agent first. All other\n RDBMS types accept placeholder credentials that satisfy the per-type required fields.\n - |-\n Celigo has native support for these database systems:\n - MySQL, MariaDB\n - PostgreSQL\n - Microsoft SQL Server (mssql), Azure Synapse (azuresynapse)\n - Oracle\n - Snowflake\n - Google BigQuery\n - Amazon Redshift\n\n ## REQUIRED FIELDS\n\n The Celigo backend rejects the connection POST with HTTP 422 if these\n type-specific required fields are missing. The rules are enforced by\n server-side validation when the connection is saved.\n\n - `type` — always required; selects the database system.\n - `host` — required for every type EXCEPT `bigquery` and `redshift`.\n - `database` — required for every type EXCEPT `oracle` (uses `serviceName`)\n and `bigquery` (uses `bigquery.dataset`).\n - `user` — required for every type EXCEPT `bigquery`, `redshift`, and\n `mssql` / `azuresynapse` with `mssql.authType=azure-service-principal`.\n - `password` — required when no SSL cert material is provided AND the\n type is NOT `bigquery`, `redshift`, `snowflake`, or `mssql` /\n `azuresynapse` with `azure-service-principal` auth. When SSL cert\n material IS provided without a password, both `ssl.key` and `ssl.cert`\n become required.\n - **Snowflake** — additionally requires `snowflake.warehouse` and\n `snowflake.authType`. When `snowflake.authType=keyPair`, also\n requires the `key` field at the rdbms level (the RSA private key).\n When `snowflake.authType=basic`, requires `password`.\n - **BigQuery** — requires `bigquery.projectId`, `bigquery.dataset`,\n `bigquery.clientEmail`, and `bigquery.privateKey`. No top-level\n `host`/`database`/`user`/`password`.\n - **Redshift** — always requires `database` and `redshift.region`; no\n top-level `host`/`password`. Two auth modes selected by\n `redshift.authType`: `accesskey` (the default when omitted) requires\n `redshift.aws.accessKeyId` + `redshift.aws.secretAccessKey` and\n rejects `workgroupName`; `awsIam` requires `_iClientId` (an `awsIam`\n iClient holding the role ARN) plus exactly one of\n `redshift.clusterIdentifier` (provisioned cluster) or\n `redshift.workgroupName` (Redshift Serverless).\n - **MSSQL / Azure Synapse with `mssql.authType=azure-service-principal`**\n — requires `_iClientId` referencing an `azureserviceprincipal` iClient\n (the Microsoft Entra tenant id, client id and client secret or\n certificate live in the iClient); `user` and `password` are not used.\n `_iClientId` with `basic` auth is rejected. Both types share the\n `mssql` sub-object; `azuresynapse` is cloud-only, and the SQL Server\n connection form offers service-principal auth in Cloud mode only — it\n saves `basic` for an on-premise connection (`_agentId` set).\n - **Oracle** — runs in agent mode only, so requires `_agentId` on the\n parent connection object. Uses `serviceName` instead of `database`.\n Optionally also takes `serverType` and `instanceName`.\n\n ## PLACEHOLDER / DUMMY RDBMS CONNECTIONS\n\n For Oracle, placeholder connections cannot be created without a real\n `_agentId` — the validator will reject them. Direct the user to install\n a Celigo Agent first. For all other RDBMS types, a placeholder can be\n created with dummy credentials matching the rules above.\n x-celigo-ui-override: >-\n Several requireds mirror the connection form rather than the API: snowflake.warehouse,\n redshift.clusterIdentifier, redshift.user, and mssql version. The API creates connections\n without them (live-verified 201), but the form requires them and a functional connection\n needs them. For mysql, postgresql, and mariadb the form makes password conditional — not\n required when a full SSL client certificate (ssl.ca, ssl.key, ssl.cert) is supplied instead;\n the conditional below keeps password required for the common (non-SSL) path, which is the\n only path the API enforces.\n required:\n - type\n properties:\n type:\n type: string\n enum:\n - mysql\n - postgresql\n - mssql\n - snowflake\n - oracle\n - bigquery\n - redshift\n - mariadb\n - azuresynapse\n x-enumDescriptions:\n mysql: MySQL database (default port 3306).\n postgresql: PostgreSQL database (default port 5432).\n mssql: Microsoft SQL Server (default port 1433).\n snowflake: Snowflake Data Cloud (requires snowflake.warehouse).\n oracle: Oracle Database; runs in agent mode and requires a connection-level _agentId (default port 1521, uses serviceName instead of database).\n bigquery: Google BigQuery; requires service account credentials in the bigquery sub-object.\n redshift: Amazon Redshift — provisioned clusters or Redshift Serverless; authenticates with static access keys or an AWS IAM role iClient (redshift.authType).\n mariadb: MariaDB database (default port 3306).\n azuresynapse: Azure Synapse Analytics (default port 1433).\n description: |-\n The specific relational database system to connect to. Determines the SQL dialect,\n connection driver, default port, and which additional sub-fields are required.\n examples:\n - postgresql\n host:\n type: string\n description: |\n Database server hostname or IP address.\n Required for all types except BigQuery (which uses Google's API endpoints) and Redshift\n (which is reached through its cluster identifier and region instead of a host).\n\n For Snowflake, use the account URL format: \"account_identifier.snowflakecomputing.com\".\n examples:\n - db.example.com\n x-celigo-ai-guidance:\n - |-\n For Snowflake, use the account URL format: \"account_identifier.snowflakecomputing.com\".\n For Redshift, use the cluster endpoint: \"cluster-name.region.redshift.amazonaws.com\".\n port:\n type: number\n description: |\n Database server port number. If omitted, uses the default port for the database type:\n - MySQL/MariaDB: 3306\n - PostgreSQL: 5432\n - MS SQL/Azure Synapse: 1433\n - Oracle: 1521\n - Snowflake: 443\n - Redshift: 5439\n minimum: 1\n maximum: 65535\n examples:\n - 5432\n database:\n type: string\n description: |\n Database name to connect to. Required for most types.\n\n For Oracle, use the serviceName field instead of database.\n For BigQuery, use bigquery.dataset to specify the target dataset.\n examples:\n - orders_prod\n instanceName:\n type: string\n description: |\n Named instance identifier, used when the server hosts multiple named database instances\n (primarily MS SQL Server). Leave empty for a default instance.\n examples:\n - SQLEXPRESS\n x-celigo-ai-guidance:\n - |-\n Named instance identifier. Used by MS SQL Server and Oracle when the server\n hosts multiple database instances. Not required for default instances.\n user:\n type: string\n description: |\n Database username for authentication. Required for all types except\n BigQuery (service account auth), Redshift, and `mssql` / `azuresynapse`\n with `mssql.authType=azure-service-principal`, where the Entra principal\n in the iClient signs in and a `user` sent anyway is stored unused.\n examples:\n - integration_user\n password:\n type: string\n description: Database password (encrypted at rest). Required alongside user for password-based auth.\n writeOnly: true\n x-celigo-ui-override: >-\n For mysql, postgresql, and mariadb the connection form makes password conditional: it is\n not required when a full SSL client certificate (ssl.ca, ssl.key, and ssl.cert) is supplied\n instead. The conditional requireds below keep password required for the common non-SSL path.\n examples:\n - \"s3cr3t-db-passw0rd\"\n version:\n type: string\n enum:\n - SQL Server 2008 R2\n - SQL Server 2012\n - SQL Server 2014\n - SQL Server 2016\n - SQL Server 2017\n - Azure\n x-enumDescriptions:\n SQL Server 2008 R2: SQL Server 2008 R2. No longer supported by Microsoft.\n SQL Server 2012: SQL Server 2012.\n SQL Server 2014: SQL Server 2014.\n SQL Server 2016: SQL Server 2016.\n SQL Server 2017: SQL Server 2017 or later.\n Azure: Azure SQL Database or Azure Synapse Analytics. Set automatically for the azuresynapse type.\n description: |-\n SQL Server engine version, which selects driver compatibility behavior. Applies to mssql\n and azuresynapse connections only (azuresynapse is always \"Azure\").\n x-celigo-ui-override: >-\n Required by the connection form for mssql (the SQL server version selector). The API\n creates the connection without it (live-verified 201); encoded here to mirror the form.\n examples:\n - SQL Server 2017\n serviceName:\n type: string\n description: |\n Oracle service name, supplied instead of the database field for Oracle connections.\n This is the TNS service name or pluggable database (PDB) service name.\n examples:\n - ORCLPDB1\n serverType:\n type: string\n enum:\n - dedicated\n - shared\n - pooled\n x-enumDescriptions:\n dedicated: Each connection gets its own server process, best for heavy workloads.\n shared: Connections share a pool of server processes for better resource efficiency.\n pooled: Database Resident Connection Pooling (DRCP), best for many short-lived connections.\n description: |-\n Oracle server connection type. Controls the server process model used for connections.\n examples:\n - dedicated\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent database connections.\n Set based on the database server's connection limit and available resources.\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |\n Target concurrency level for auto-scaling. The system adjusts the number of\n concurrent connections between 1 and this value based on performance feedback.\n minimum: 1\n maximum: 50\n examples:\n - 10\n disableStrictSSL:\n type: boolean\n description: |\n When true, disables strict SSL/TLS certificate validation for the database connection.\n Only use for development/testing with self-signed certificates.\n default: false\n snowflake:\n type: object\n description: |\n Snowflake-specific configuration. Required when type is \"snowflake\".\n required:\n - authType\n properties:\n warehouse:\n type: string\n description: |-\n Snowflake virtual warehouse that provides compute resources for queries.\n Must be a warehouse the user's role can access.\n x-celigo-ui-override: >-\n Required by the connection form. The API creates the connection without it\n (live-verified 201), but queries fail without a warehouse, so the form requires it.\n x-celigo-ai-guidance:\n - Not enforced at connection-create time, but queries fail without it — set it for any functional connection.\n - |-\n Snowflake virtual warehouse name. REQUIRED for Snowflake connections.\n The warehouse provides compute resources for queries. Must be a warehouse\n the user role has access to.\n examples:\n - COMPUTE_WH\n schema:\n type: string\n description: |\n Default Snowflake schema. If omitted, queries must fully-qualify table names\n (e.g., DATABASE.SCHEMA.TABLE).\n examples:\n - PUBLIC\n role:\n type: string\n description: |\n Snowflake security role to use for the session. Determines which databases,\n schemas, and warehouses are accessible. Defaults to the user's default role.\n examples:\n - SYSADMIN\n authType:\n type: string\n enum:\n - keyPair\n - basic\n x-celigo-deprecated-enum-values:\n # `basic` (username/password) is deprecated for Snowflake. Kept in source (existing\n # connections may still report it) but stripped from the published bundle: the connection\n # form hard-locks Snowflake to keyPair (the authType dropdown is disabled even on a new\n # draft), reflecting Snowflake's move away from single-factor password auth. New consumers\n # must use keyPair.\n - basic\n x-enumDescriptions:\n keyPair: RSA key-pair authentication using a private key; the connection form's only authentication type for new Snowflake connections.\n basic: \"Deprecated: username and password authentication. The connection form now defaults to keyPair and only offers basic for connections that already use it.\"\n description: |-\n Authentication type for Snowflake. keyPair uses RSA key-pair authentication and requires\n the connection's key field. It is the only type the connection form offers for new\n connections (password-based auth is no longer available).\n x-celigo-ai-guidance:\n - keyPair is the form default and requires the key field — the POST fails 422 \"Expected field: key to be present.\" without it. Prefer keyPair; basic is deprecated.\n examples:\n - keyPair\n mssql:\n type: object\n description: |-\n Microsoft SQL Server / Azure Synapse-specific configuration. Read for\n both the `mssql` and the `azuresynapse` types — Azure Synapse\n Analytics shares SQL Server's authentication model and this\n sub-object.\n properties:\n authType:\n type: string\n enum:\n - basic\n - azure-service-principal\n x-enumDescriptions:\n basic: Database user — SQL authentication with `user` and `password`\n azure-service-principal: Microsoft Entra service principal held in the `azureserviceprincipal` iClient referenced by `_iClientId`; `user` and `password` are not used\n description: |-\n How a Microsoft SQL Server or Azure Synapse connection\n authenticates. Defaults to `basic` when omitted (the connection\n form's \"Database user\"). With `azure-service-principal` the\n connection signs in as the Entra application registered in the\n iClient — a client secret, or on SQL Server a certificate — and\n `_iClientId` must reference it. The SQL Server connection form\n offers `azure-service-principal` in Cloud mode only and saves\n `basic` for an on-premise connection (`_agentId` set).\n default: basic\n examples:\n - basic\n x-celigo-ai-guidance:\n - |-\n With azure-service-principal, omit user and password: the API does not reject them —\n it stores them unused on the connection (live-verified 201 with both present), while\n the connection form removes them on save. Set them only for basic.\n - |-\n A certificate-method azureserviceprincipal iClient is offered by the form on Microsoft\n SQL Server connections only; the Azure Synapse form's picker lists client-secret\n iClients. The API accepts either on either type (live-verified 201), so follow the\n form: bind a certificate iClient to mssql connections only.\n bigquery:\n type: object\n description: |\n Google BigQuery-specific configuration. Required when type is \"bigquery\".\n Uses Google Cloud service account credentials for authentication.\n properties:\n projectId:\n type: string\n description: |\n Google Cloud project ID that contains the BigQuery datasets.\n Found in the Google Cloud Console project settings.\n examples:\n - my-gcp-project\n dataset:\n type: string\n description: |\n Default BigQuery dataset name.\n Queries will target tables within this dataset unless fully-qualified names are used.\n examples:\n - analytics\n clientEmail:\n type: string\n format: email\n description: |\n Google Cloud service account email address.\n The service account must have BigQuery Data Editor and BigQuery Job User roles.\n examples:\n - [email protected]\n privateKey:\n type: string\n description: |\n Google Cloud service account private key in PEM format (encrypted at rest).\n Downloaded as part of the service account JSON key file.\n writeOnly: true\n redshift:\n type: object\n description: |\n Amazon Redshift-specific configuration. `region` is always required.\n Credentials depend on `authType`: static access keys in `aws` for\n `accesskey` (the default), or an `awsIam` iClient referenced by\n `rdbms._iClientId` for `awsIam`. The top-level user and password are optional.\n properties:\n authType:\n type: string\n enum: [accesskey, awsIam]\n default: accesskey\n x-enumDescriptions:\n accesskey: Authenticate with static AWS access keys in `aws.accessKeyId` / `aws.secretAccessKey` — the connection form's \"Username & Password\" option (its fields are Access key ID, Secret access key and the database Username).\n awsIam: Authenticate by assuming the AWS IAM role held in the iClient referenced by `rdbms._iClientId`; no static keys stored on the connection — the form's \"AWS IAM role\" option.\n description: |-\n Selects the Redshift authentication mode; omitting it behaves as\n `accesskey`. With `awsIam`, the platform assumes the iClient's\n role and requires exactly one of `clusterIdentifier` (provisioned\n cluster) or `workgroupName` (Redshift Serverless) — supplying\n both or neither fails with 422. A bulk-load import saves against\n either mode, cluster or Serverless workgroup alike.\n aws:\n type: object\n description: |-\n Static AWS access keys, used when `authType` is `accesskey` (or\n omitted). Not used with `awsIam` — credentials then come from the\n iClient.\n properties:\n accessKeyId:\n type: string\n description: AWS access key ID for IAM authentication.\n examples:\n - AKIA_EXAMPLE_KEY_ID\n secretAccessKey:\n type: string\n description: AWS secret access key (encrypted at rest).\n writeOnly: true\n examples:\n - wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n clusterIdentifier:\n type: string\n description: |-\n Redshift cluster identifier, used with the region to reach a\n provisioned cluster. With `awsIam` auth, exactly one of\n `clusterIdentifier` or `workgroupName` must be set.\n x-celigo-ui-override: >-\n Required by the connection form for access-key auth. The API creates the connection\n without it (live-verified: omitting it returns 201), but the form requires it.\n examples:\n - my-redshift-cluster\n workgroupName:\n type: string\n description: |-\n Redshift Serverless workgroup to connect to instead of a\n provisioned cluster. Only valid when `authType` is `awsIam` —\n the API rejects it with `accesskey` auth (422 \"Redshift\n Serverless (workgroupName) requires authType=awsIam\") — and is\n mutually exclusive with `clusterIdentifier`.\n examples:\n - my-serverless-workgroup\n region:\n type: string\n description: |\n AWS region where the Redshift cluster is deployed.\n examples:\n - us-east-1\n enum:\n - us-east-1\n - us-east-2\n - us-west-1\n - us-west-2\n - eu-west-1\n - eu-west-2\n - eu-west-3\n - eu-north-1\n - eu-central-1\n - ap-southeast-1\n - ap-southeast-2\n - ap-northeast-1\n - ap-northeast-2\n - ap-south-1\n - sa-east-1\n - ca-central-1\n x-enumDescriptions:\n us-east-1: US East (N. Virginia).\n us-east-2: US East (Ohio).\n us-west-1: US West (N. California).\n us-west-2: US West (Oregon).\n eu-west-1: Europe (Ireland).\n eu-west-2: Europe (London).\n eu-west-3: Europe (Paris).\n eu-north-1: Europe (Stockholm).\n eu-central-1: Europe (Frankfurt).\n ap-southeast-1: Asia Pacific (Singapore).\n ap-southeast-2: Asia Pacific (Sydney).\n ap-northeast-1: Asia Pacific (Tokyo).\n ap-northeast-2: Asia Pacific (Seoul).\n ap-south-1: Asia Pacific (Mumbai).\n sa-east-1: South America (Sao Paulo).\n ca-central-1: Canada (Central).\n x-lowercase: true\n useSSL:\n type: boolean\n writeOnly: true\n description: |-\n When true, the database connection is made over SSL/TLS and the certificate material in\n `ssl` applies — the connection form's **Use SSL** switch (offered for MySQL, MariaDB and\n PostgreSQL). Accepted on POST and PUT only: the platform stores it as `ssl.enabled`, which\n is the field GET returns. A PUT that omits `useSSL` clears the stored `ssl.enabled` — send\n it on every update that should keep SSL on.\n examples: [true]\n x-celigo-ai-guidance:\n - |-\n A body built from a GET carries `ssl.enabled` but never `useSSL`, so sending it back as a\n PUT turns SSL off: add `\"useSSL\": true` to every update of a connection that uses SSL.\n Setting `ssl.enabled` in the body changes nothing (verified live 2026-10-23 on a PostgreSQL\n connection: a PUT of the GET body cleared `ssl`, a PUT with `useSSL: true` set it again,\n and a PUT with `ssl.enabled: true` but no `useSSL` cleared it).\n ssl:\n allOf:\n - $ref: './ssl.yml#/SSL'\n - type: object\n properties:\n enabled:\n type: boolean\n readOnly: true\n description: |-\n When true, SSL/TLS is on for this database connection. Set from `useSSL` on\n write and returned here on read; a value sent in this field is ignored.\n options:\n type: array\n description: |\n Additional database driver connection options as name/value pairs.\n Use for driver-specific settings not covered by the standard fields\n (e.g., connection timeout, charset, application name).\n items:\n type: object\n properties:\n name:\n type: string\n description: Option name (driver-specific).\n examples:\n - connectTimeout\n value:\n type: string\n description: Option value.\n examples:\n - \"30\"\n required:\n - name\n - value\n key:\n type: string\n writeOnly: true\n description: |-\n RSA private key (PEM-encoded, encrypted at rest). Required when type is `snowflake`\n and `snowflake.authType` is `keyPair`. Not used by any other database type.\n passphrase:\n type: string\n writeOnly: true\n description: |-\n Passphrase that decrypts the RSA private key in the key field, when that key is\n encrypted (encrypted at rest). Used only for `snowflake` with `snowflake.authType`\n `keyPair`; omit when the private key is unencrypted.\n examples:\n - \"key-passphrase-EXAMPLE\"\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n description: |-\n Reference to an iClient holding auth credentials, stored inside the\n rdbms object. Required when type is `mssql` or `azuresynapse` and\n `mssql.authType` is `azure-service-principal` (an\n `azureserviceprincipal` iClient — the Microsoft Entra tenant id,\n client id and client secret or certificate), and when type is\n `redshift` and `redshift.authType` is `awsIam` (an `awsIam`-provider\n iClient holding the role ARN to assume). On `mssql` / `azuresynapse`\n it is rejected when `mssql.authType` is `basic` or omitted. For\n Redshift the iClient must carry `awsIam.roleArn`, and that role's name\n must start with `celigo-data-warehouse-adaptor-` — the data-warehouse\n service assumes only roles in that family, so a role created for an S3\n or HTTP connection cannot be reused here.\n examples:\n - 66a1b2c3d4e5f60718293a4b\n x-celigo-ai-guidance:\n - |-\n For a mssql or azuresynapse connection with mssql.authType \"azure-service-principal\",\n _iClientId is required (otherwise 422 missing_required_field on rdbms._iClientId\n \"Expected field: _iClientId to be present.\") and must reference an azureserviceprincipal\n iClient (otherwise 422 invalid_field on rdbms._iClientId \"IClient provider must be\n azureserviceprincipal for Service Principal authentication.\"). The same iClient can back\n Azure Data Lake Storage Gen2, SQL Server and Synapse connections.\n - |-\n With mssql.authType \"basic\" (or omitted) on mssql / azuresynapse, do not set _iClientId:\n 422 invalid_field on rdbms._iClientId \"The _iClientId field should not be set when using\n basic authentication. Remove _iClientId or switch to azure-service-principal\n authentication.\"\n - |-\n For a Redshift connection with redshift.authType \"awsIam\", the referenced iClient must\n have awsIam.roleArn set (otherwise 422 missing_required_field on rdbms._iClientId\n \"Expected field: awsIam.roleArn to be present.\") and its role name must start with\n \"celigo-data-warehouse-adaptor-\" (otherwise 422 invalid_field_value on rdbms._iClientId\n \"Invalid value for field \\\"_iClientId\\\": Your role ARN's name must begin with\n celigo-data-warehouse-adaptor.\"). Do not reuse a celigo-file-adaptor- or\n celigo-http-adaptor- role.\n - |-\n With redshift.authType \"awsIam\", omit the top-level user and password — the API does not\n reject them, it stores them on a connection whose form has no field that could ever\n clear them; the database user is derived from the assumed role at runtime.\n # API requireds are enforced via 201/422 on connection POST.\n # `oracle` also requires a connection-level `_agentId` (validator error `agent_mode_only`) —\n # cross-level, so documented in prose, not encoded here.\n # snowflake: keyPair requires `key` (422 \"Expected field: key\" without it);\n # password is required only for basic (keyPair+key with no password → 201). `snowflake.warehouse`\n # is NOT API-enforced (keyPair+key, no warehouse → 201) but the form requires it — encoded as a\n # required via x-celigo-ui-override.\n # redshift: aws.accessKeyId, aws.secretAccessKey, region, and database are API-required\n # (422 without each); user and password are API-optional (IAM path → 201 without them).\n # `clusterIdentifier` and `user` are NOT API-enforced (omitting either → 201) but the form requires\n # them — encoded as requireds via x-celigo-ui-override. redshift has no host/password fields in the form.\n # mssql `version` is form-required but NOT API-enforced (201 without it, 2026-06-11) — x-celigo-ui-override.\n # redshift authType (2026-08-01, live-verified on connection POST): awsIam ⇒ rdbms._iClientId required\n # (422 \"Expected field: _iClientId\"); workgroupName with accesskey ⇒ 422 \"Redshift Serverless\n # (workgroupName) requires authType=awsIam\"; awsIam ⇒ exactly one of clusterIdentifier/workgroupName\n # (422 \"Exactly one of clusterIdentifier or workgroupName must be set when authType is awsIam\").\n # redshift awsIam iClient rules (2026-10-01, live-verified on connection POST): the referenced iClient\n # needs awsIam.roleArn (422 missing_required_field \"Expected field: awsIam.roleArn to be present.\" on\n # rdbms._iClientId) and a role name starting with celigo-data-warehouse-adaptor- (422 invalid_field_value\n # 'Invalid value for field \"_iClientId\": Your role ARN's name must begin with celigo-data-warehouse-adaptor.').\n # A stray top-level user/password on the awsIam path is stored, not rejected (201).\n # Per-database conditional requireds mirror the connection form — nested if/else-if (no allOf).\n # mssql / azuresynapse authType (2026-10-12, live-verified on connection POST, both types):\n # azure-service-principal ⇒ rdbms._iClientId required (422 \"Expected field: _iClientId to be\n # present.\"); basic + _iClientId ⇒ 422 invalid_field; a non-azureserviceprincipal iClient ⇒ 422\n # invalid_field; user/password sent with azure-service-principal are stored, not rejected (201).\n # azuresynapse has no `version` requirement (the server stamps \"Azure\"), so it keeps its own branch\n # instead of sharing mssql's form-required `version`.\n # mssql, azuresynapse, snowflake, and redshift keep their authType sub-conditions nested inside their own branches.\n if:\n properties:\n type:\n enum:\n - mysql\n - postgresql\n - mariadb\n required:\n - type\n then:\n required:\n - host\n - database\n - user\n - password\n else:\n if:\n properties:\n type:\n const: mssql\n required:\n - type\n then:\n if:\n properties:\n mssql:\n properties:\n authType:\n const: azure-service-principal\n required:\n - authType\n required:\n - mssql\n then:\n required:\n - host\n - database\n - version\n - _iClientId\n else:\n required:\n - host\n - database\n - version\n - user\n - password\n else:\n if:\n properties:\n type:\n const: azuresynapse\n required:\n - type\n then:\n if:\n properties:\n mssql:\n properties:\n authType:\n const: azure-service-principal\n required:\n - authType\n required:\n - mssql\n then:\n required:\n - host\n - database\n - _iClientId\n else:\n required:\n - host\n - database\n - user\n - password\n else:\n if:\n properties:\n type:\n const: snowflake\n required:\n - type\n then:\n required:\n - host\n - database\n - user\n properties:\n snowflake:\n required:\n - authType\n - warehouse\n if:\n properties:\n snowflake:\n properties:\n authType:\n const: keyPair\n required:\n - authType\n required:\n - snowflake\n then:\n required:\n - key\n else:\n required:\n - password\n else:\n if:\n properties:\n type:\n const: oracle\n required:\n - type\n then:\n required:\n - host\n - user\n - password\n else:\n if:\n properties:\n type:\n const: bigquery\n required:\n - type\n then:\n required:\n - bigquery\n properties:\n bigquery:\n required:\n - projectId\n - dataset\n - clientEmail\n - privateKey\n else:\n if:\n properties:\n type:\n const: redshift\n required:\n - type\n then:\n required:\n - database\n - user\n - redshift\n properties:\n redshift:\n required:\n - region\n if:\n required:\n - redshift\n properties:\n redshift:\n required:\n - authType\n properties:\n authType:\n const: awsIam\n then:\n required:\n - _iClientId\n properties:\n redshift:\n oneOf:\n - required: [clusterIdentifier]\n not:\n required: [workgroupName]\n - required: [workgroupName]\n not:\n required: [clusterIdentifier]\n else:\n properties:\n redshift:\n required:\n - aws\n - clusterIdentifier\n not:\n required: [workgroupName]\n properties:\n aws:\n required:\n - accessKeyId\n - secretAccessKey\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":35429,"content_sha256":"c21d9bfd5a7b3f3ab31fdc83fb80252e116216c6247be7c8b617e20182ef843a"},{"filename":"references/schemas/request.yml","content":"Request:\n type: object\n description: Fields that can be sent when creating or updating a connection.\n properties:\n name:\n type: string\n minLength: 1\n description: Display name for the connection.\n x-celigo-ai-guidance:\n - Name the connection after the ONE system it authenticates to — the application, plus the account, store, or environment when that distinguishes it (e.g. \"Shopify - mystore\", \"NetSuite Non-Production\").\n - Never name a connection after a flow or use case, and never include a second application in the name (not \"Shopify to NetSuite Customer Sync\"). Connections are account-level resources reused across many integrations; a use-case name hides which system the credentials belong to and misleads later reuse.\n examples: [\"Salesforce Production\", \"NetSuite Non-Production\", \"PostgreSQL Orders DB\"]\n maxLength: 100\n type:\n type: string\n description: Connection type, which determines the authentication and connectivity options available and which config object must be supplied.\n enum:\n - netsuite\n - salesforce\n - ftp\n - s3\n - wrapper\n - http\n - rdbms\n - mongodb\n - as2\n - filesystem\n - mcp\n - dynamodb\n - jdbc\n - van\n - rest\n x-enumDescriptions:\n netsuite: NetSuite ERP connection using token-based authentication (TBA).\n salesforce: Salesforce CRM connection with OAuth 2.0 authentication.\n ftp: FTP, SFTP, or FTPS file transfer connection.\n s3: Amazon S3 cloud storage connection, authenticated with an access key pair or an AWS IAM role (`s3.authType`).\n wrapper: Wrapper connection that delegates to another connection type.\n http: Generic HTTP/REST API connection with full configuration control.\n rdbms: Native relational-database connection — MySQL, PostgreSQL, MariaDB, Microsoft SQL Server, Azure Synapse, Oracle, Snowflake, Google BigQuery, Amazon Redshift (the database is `rdbms.type`).\n mongodb: MongoDB NoSQL database connection.\n as2: AS2 (Applicability Statement 2) EDI connection.\n filesystem: Local or network filesystem connection (requires an Agent).\n mcp: MCP (Model Context Protocol) server connection.\n dynamodb: Amazon DynamoDB NoSQL database connection.\n jdbc: JDBC connection for relational systems without a native `rdbms` type (Databricks, Db2, Workday, NetSuite JDBC) and for the driver-specific paths `jdbc.type` names (Oracle Thin, SQL Server with Active Directory); Redshift, BigQuery and Snowflake are `rdbms` types.\n van: Value-Added Network connection for EDI document exchange.\n rest: REST connection driven by a pre-built HTTP Connector template. Deprecated — use `http` instead.\n externalId:\n type: string\n description: External identifier for the connection, often used to correlate it with a record in a third-party system.\n examples: [\"erp-conn-001\"]\n assistant:\n type: string\n description: |-\n Lowercase application name for HTTP connections to systems with an integrator.io\n adaptor (e.g. \"shopify\", \"ebay\"). Only applies to http connections. The platform\n checks the slug against its current adaptor list — an unknown value fails the save\n with 422 `enum` — and uses it to resolve the HTTP connector link on every save (see\n `http._httpConnectorId`), so send it only when the application really is a legacy\n adaptor: on an Azure Data Lake Storage Gen2 connection it drops the connector ids.\n examples: [\"shopify\"]\n x-celigo-ai-guidance:\n - |-\n Omit `assistant` on an Azure Data Lake Storage Gen2 connection. With\n `assistant: \"azuredatalakestoragegen2\"` (or any other slug) the save answers 201/200\n but stores no `http._httpConnectorId` or `http._httpConnectorVersionId`; the\n connection form never sends it. Send the ADLS connector id and version id without\n `assistant` — a PUT that drops `assistant` and re-sends them restores the link.\n - |-\n A value outside the platform's adaptor list fails with 422 `enum` on `assistant`\n (\"`\u003cvalue>` is not a valid enum value for path `assistant`.\"); for a connector-framework\n application with no legacy adaptor, link it through `http._httpConnectorId` instead.\n accessScope:\n type: object\n description: |-\n What a Celigo APIs connection (`assistant: integratorceligoapi`) may reach in the\n account: the account's custom APIs, listeners, standard integrator.io APIs and Celigo\n Storage folders. A Celigo APIs connection cannot be created without it; an update that\n omits it leaves the stored scope unchanged. The connection document never carries it —\n the stored scope is read from `GET /v1/accessScope/connections/{_id}`.\n required: [type]\n properties:\n type:\n type: string\n enum: [full, custom, integration]\n x-enumDescriptions:\n full: Every custom API, listener and standard integrator.io API in the account, and every Celigo Storage folder\n custom: Only the APIs, listeners and Celigo Storage folders listed in the sibling arrays\n integration: Only the integrations listed in `_integrationIds`\n description: |-\n How much of the account the connection may reach. Each type takes its own\n selections: `full` takes none, `custom` takes APIs, listeners and folder paths,\n `integration` takes integrations only.\n _apiIds:\n type: array\n items:\n type: string\n format: objectId\n x-celigo-refModel: apis\n description: Custom APIs the connection may invoke. Present when `type` is `custom`.\n _exportIds:\n type: array\n items:\n type: string\n format: objectId\n x-celigo-refModel: exports\n description: Listeners (webhook exports) the connection may trigger. Present when `type` is `custom`.\n _integrationIds:\n type: array\n items:\n type: string\n format: objectId\n x-celigo-refModel: integrations\n description: Integrations whose resources the connection may reach. Present when `type` is `integration`.\n _fileStoragePaths:\n type: array\n items:\n type: string\n description: |-\n Celigo Storage folder paths the connection may read and write, matched as prefixes\n — each path also grants every folder beneath it, `/` alone grants every folder, and\n there are no wildcards. Present when `type` is `custom`; a `custom` connection with\n the field omitted or empty has no Celigo Storage access.\n examples: [[\"/Reports/\", \"/Inbound/EDI/\"], [\"/\"]]\n # The server's cross-field rules (422 invalid_access_scope), nested else-if, stack-style.\n if: { properties: { type: { const: full } }, required: [type] }\n then:\n properties:\n _apiIds: { maxItems: 0 }\n _exportIds: { maxItems: 0 }\n _integrationIds: { maxItems: 0 }\n _fileStoragePaths: { maxItems: 0 }\n else:\n if: { properties: { type: { const: integration } }, required: [type] }\n then:\n required: [_integrationIds]\n properties:\n _integrationIds: { minItems: 1 }\n _apiIds: { maxItems: 0 }\n _exportIds: { maxItems: 0 }\n _fileStoragePaths: { maxItems: 0 }\n else:\n properties:\n _integrationIds: { maxItems: 0 }\n x-celigo-ai-guidance:\n - |-\n A Celigo APIs connection POST without `accessScope` fails with 422 `missing_required_field`\n (\"Scope is required for this connection. Please select Full access or Custom.\"); a PUT\n without it is accepted and the stored scope is unchanged. A `type` outside the enum fails\n with 422 `enum`.\n - |-\n Each mismatch between `type` and the selections fails with 422 `invalid_access_scope` and\n names the field: `full` with any of `_apiIds`, `_exportIds`, `_integrationIds` or\n `_fileStoragePaths`; `custom` with `_integrationIds` (\"Use \\\"integration\\\" access type\");\n `integration` with no `_integrationIds`, or with `_apiIds`, `_exportIds` or\n `_fileStoragePaths`. An id that is not an existing API or integration fails with 422\n `invalid_ref`.\n - |-\n Choose the narrowest `type` the connection's use needs: a flow that reads or writes Celigo\n Storage files → `custom` with the folder paths it uses (`/Reports/` grants that folder and\n everything beneath it); specific custom APIs or listeners → `custom` with their ids; the\n standard integrator.io REST APIs → `full`. A `custom` connection with `_fileStoragePaths`\n omitted or empty has no storage access — its storage step fails at run time with 401.\n - |-\n The connection document never carries `accessScope`; read the stored scope from\n `GET /v1/accessScope/connections/{_id}` (`scope`, `apis`, `exports`, `integrations`,\n `fileStoragePaths`) rather than inferring it from the document.\n _agentId:\n type: string\n format: objectId\n x-celigo-refModel: agents\n description: |-\n Reference to a Celigo on-premise Agent. Required for types that need local network or\n filesystem access (filesystem, jdbc agent/activedirectory, Oracle rdbms, and on-premise\n mongodb). The agent establishes a secure tunnel between the on-premise environment and\n integrator.io.\n examples: [\"5f8d43a1b9e5a80011a35f2c\"]\n _borrowConcurrencyFromConnectionId:\n type: string\n format: objectId\n x-celigo-refModel: connections\n description: |-\n Reference to another connection to share concurrency limits with. When set, this\n connection's traffic counts against the referenced connection's limit instead of its own,\n and its own concurrency and auto-recovery settings have no effect. One level only: the\n referenced connection may not itself borrow, and a connection that others borrow from\n cannot start borrowing. A connection cannot reference itself (422).\n examples: [\"615dfa0742763671275b70ab\"]\n x-celigo-ai-guidance:\n - |-\n Set this when several connections target one external account whose API enforces a\n single account-wide concurrency limit (for example one NetSuite account): put the limit\n on one parent connection and point the others here, so their combined traffic can never\n exceed it.\n - |-\n A borrower drains through the parent's queue as well as its ceiling, so a high-volume\n borrower competes with the parent's own flows — settle the priority split before\n choosing who borrows from whom.\n autoRecoverRateLimitErrors:\n type: boolean\n default: true\n description: |-\n When true, rate-limit errors from the target system trigger automatic recovery — concurrency\n drops to 1 and climbs back toward the adaptor block's `targetConcurrencyLevel`, which is the\n throughput lever while this is on. Turning it on copies the current `concurrencyLevel` into\n the target; turning it off unsets the target and leaves `concurrencyLevel` at its current value.\n A create gets `true` unless it sends `false`; while it is true, set a new connection's level\n with `targetConcurrencyLevel`. On `http`, `ftp`, `rdbms` and `mongodb` connections the create\n stores the target sent, or the adaptor's default without one, as both `concurrencyLevel` and\n `targetConcurrencyLevel`, whatever `concurrencyLevel` the body carried: 1 for `ftp`, 5 for\n `rdbms` and `mongodb`, and 25 for `http` where the license's `concurrency` is at least 25, so\n such an `http` create that sends only `concurrencyLevel: 10` is stored at 25. To keep the\n `concurrencyLevel` you send, create with this `false`.\n Recovery never runs on `ftp` connections: FTP errors aren't treated as rate limits.\n __integrationIds:\n type: array\n maxItems: 100\n items:\n type: string\n format: objectId\n x-celigo-refModel: integrations\n description: |-\n Integrations to register the new connection on immediately after creation, making it\n available for use within them. Only honored on `POST /v1/connections` (ignored on PUT)\n and never persisted on the connection document. Ids are validated before the connection\n is saved; registration runs after the save, and per-integration failures are reported in\n `__failedIntegrationRegistrations` on the 201 response without rolling back the new\n connection.\n x-celigo-ai-guidance:\n - |-\n Invalid input rejects the whole request without creating the connection: a non-array value\n or duplicate ids fail with 422 invalid_request, an element that is not a valid ObjectId fails\n with 422 invalid_ref naming __integrationIds[i], an integration that does not exist in the\n account fails with 404, and more than 100 ids fails with 400 batch_size_exceeded.\n - |-\n Integrations installed through an Integration App cannot be registered this way — the\n connection is still created (201) and the failure is reported in\n __failedIntegrationRegistrations with code not_allowed.\n examples: [[\"6a55be91d16ee8270022893e\"]]\n endUserProvidedFields:\n type: ['array', 'null']\n items:\n type: string\n description: |-\n Dot-paths of this connection's fields (for example `http.encrypted.apiKey` or\n `rdbms.user`) that each MCP end user must supply on their own `mcpChild` copy instead of\n inheriting the parent's value. Set it on the parent connection an MCP server collects\n end-user credentials for; omit it everywhere else. Omitting it (or sending `[]`) on\n `PUT` keeps the stored paths; send `null` to clear them. By the platform contract,\n changing the stored list — adding, removing, or clearing paths — invalidates the\n `mcpChild` connections end users already hold against this parent, so each of them\n sets up again through the MCP setup page before tools that use it run for them.\n x-celigo-ai-guidance:\n - |-\n List only the credential and tenant fields that differ per end user, never a path the\n account owns: `type`, `_agentId`, `wrapper._stackId`, or any `\u003cadaptor>._iClientId`\n (e.g. `http._iClientId`) fails the save with 422\n `mcp_end_user_provided_field_not_allowed`.\n - |-\n This is the only MCP end-user field writable through `/v1/connections`; the child\n connections themselves are created by the end-user setup page, and `connectionRole:\n mcpChild` in a `POST` or `PUT` body fails with 422 `mcp_child_generic_route_not_allowed`.\n examples: [[\"http.encrypted.apiKey\", \"http.unencrypted.accountId\"]]\n debugDate:\n type: string\n format: date-time\n description: Enables debug logging until this timestamp. Set to a future time to capture request/response logs.\n examples: [\"2026-01-15T09:30:00.000Z\"]\n settingsForm:\n type: object\n description: Dynamic form definition for connection-specific custom settings.\n settings:\n type: object\n description: |-\n Connection-specific settings captured by settingsForm. At runtime, steps using\n this connection read the values under the fixed scope key `connection` — e.g.\n `{{settings.connection.\u003cfieldId>}}` in Handlebars or\n `$.settings.connection.\u003cfieldId>` in Mapper 2.0 envelope references.\n pgp:\n description: Present for file-based connections (ftp, s3, filesystem, …) that encrypt or decrypt files with PGP.\n allOf:\n - $ref: './pgp.yml#/PGP'\n ssl:\n $ref: './ssl.yml#/SSL'\n # Connection type-specific config objects — supply the one matching `type`.\n netsuite:\n description: Present when `type` is `netsuite`.\n allOf:\n - $ref: './netsuite.yml#/NetSuite'\n salesforce:\n description: Present when `type` is `salesforce`.\n allOf:\n - $ref: './salesforce.yml#/Salesforce'\n ftp:\n description: Present when `type` is `ftp`.\n allOf:\n - $ref: './ftp.yml#/FTP'\n s3:\n description: Present when `type` is `s3`.\n allOf:\n - $ref: './s3.yml#/S3'\n http:\n description: Present when `type` is `http`.\n allOf:\n - $ref: './http.yml#/HTTP'\n rdbms:\n description: Present when `type` is `rdbms`.\n allOf:\n - $ref: './rdbms.yml#/RDBMS'\n mongodb:\n description: Present when `type` is `mongodb`.\n allOf:\n - $ref: './mongodb.yml#/MongoDB'\n as2:\n description: Present when `type` is `as2`.\n allOf:\n - $ref: './as2.yml#/AS2'\n filesystem:\n description: Present when `type` is `filesystem`.\n allOf:\n - $ref: './filesystem.yml#/Filesystem'\n dynamodb:\n description: Present when `type` is `dynamodb`.\n allOf:\n - $ref: './dynamodb.yml#/DynamoDB'\n jdbc:\n description: Present when `type` is `jdbc`.\n allOf:\n - $ref: './jdbc.yml#/JDBC'\n van:\n description: Present when `type` is `van`.\n allOf:\n - $ref: './van.yml#/VAN'\n mcp:\n description: Present when `type` is `mcp`.\n allOf:\n - $ref: './mcp.yml#/MCP'\n wrapper:\n description: Present when `type` is `wrapper`.\n allOf:\n - $ref: './wrapper.yml#/Wrapper'\n rest:\n deprecated: true\n description: Present when `type` is `rest`. Deprecated — superseded by `http` with a pre-built HTTP Connector template.\n allOf:\n - $ref: './rest.yml#/REST'\n required:\n - name\n - type\n # The config object matching `type` must be supplied. Nested if/else-if (no allOf), stack-style.\n # The netsuite branch also carries the per-authType form requireds (they live here, scoped to\n # type=netsuite, because jdbc connections embed a `netsuite` auth subdoc the form rules don't\n # apply to — live jdbc connections store token-auto without an account).\n if: { properties: { type: { const: netsuite } }, required: [type] }\n then:\n required: [netsuite]\n properties:\n netsuite:\n if:\n properties:\n authType:\n const: basic\n required: [authType]\n then:\n required: [email, password]\n else:\n if:\n properties:\n authType:\n const: token\n required: [authType]\n then:\n required: [account, environment, tokenId, tokenSecret]\n else:\n if:\n properties:\n authType:\n const: token-auto\n required: [authType]\n then:\n required: [account]\n else:\n if: { properties: { type: { const: salesforce } }, required: [type] }\n then: { required: [salesforce] }\n else:\n if: { properties: { type: { const: ftp } }, required: [type] }\n then: { required: [ftp] }\n else:\n if: { properties: { type: { const: s3 } }, required: [type] }\n then: { required: [s3] }\n else:\n if: { properties: { type: { const: http } }, required: [type] }\n then: { required: [http] }\n else:\n if: { properties: { type: { const: rdbms } }, required: [type] }\n then: { required: [rdbms] }\n else:\n if: { properties: { type: { const: mongodb } }, required: [type] }\n then: { required: [mongodb] }\n else:\n if: { properties: { type: { const: as2 } }, required: [type] }\n then: { required: [as2] }\n else:\n # filesystem runs on a Celigo Agent: the connection-level _agentId is API-required\n # (422 \"The file system connection requires Agent\").\n if: { properties: { type: { const: filesystem } }, required: [type] }\n then: { required: [filesystem, _agentId] }\n else:\n if: { properties: { type: { const: mcp } }, required: [type] }\n then: { required: [mcp] }\n else:\n if: { properties: { type: { const: dynamodb } }, required: [type] }\n then: { required: [dynamodb] }\n else:\n if: { properties: { type: { const: jdbc } }, required: [type] }\n then:\n required: [jdbc]\n # _agentId is API-enforced for the agent + activedirectory jdbc types (POST 422\n # agent_mode_only). Request-only (cross-level), matching filesystem.\n if:\n properties: { jdbc: { properties: { type: { enum: [agent, activedirectory] } }, required: [type] } }\n required: [jdbc]\n then: { required: [_agentId] }\n else:\n if: { properties: { type: { const: van } }, required: [type] }\n then: { required: [van] }\n else:\n if: { properties: { type: { const: wrapper } }, required: [type] }\n then:\n # _stackId required on create only (form-mirror) — the API accepts a\n # wrapper without it (POST 201). Not in the shared/response\n # schema because connector-managed wrappers (with _connectorId) omit it.\n required: [wrapper]\n properties:\n wrapper:\n required: [_stackId]\n else:\n if: { properties: { type: { const: rest } }, required: [type] }\n then: { required: [rest] }\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":22490,"content_sha256":"375fcb21af22fd8030de29cc7ee1d0294205ad163d83dd3855e1f4192d19def7"},{"filename":"references/schemas/response-base.yml","content":"ResponseBase:\n type: object\n description: Shared properties present on every connection response regardless of type.\n allOf:\n - $ref: '../common-schemas/resource-response.yml#/ResourceResponse'\n - $ref: '../common-schemas/ia-resource-response.yml#/IAResourceResponse'\n - type: object\n properties:\n name:\n type: string\n description: Display name for the connection.\n examples: [\"Salesforce Production\", \"NetSuite Non-Production\", \"PostgreSQL Orders DB\"]\n maxLength: 100\n type:\n type: string\n description: The type of connection determining which authentication and connectivity options are available\n enum:\n - netsuite\n - salesforce\n - ftp\n - s3\n - wrapper\n - http\n - rdbms\n - mongodb\n - as2\n - filesystem\n - mcp\n - dynamodb\n - jdbc\n - van\n - rest\n x-enumDescriptions:\n netsuite: NetSuite ERP connection using token-based authentication (TBA).\n salesforce: Salesforce CRM connection with OAuth 2.0 authentication.\n ftp: FTP, SFTP, or FTPS file transfer connection.\n s3: Amazon S3 cloud storage connection, authenticated with an access key pair or an AWS IAM role (`s3.authType`).\n wrapper: Wrapper connection that delegates to another connection type.\n http: Generic HTTP/REST API connection with full configuration control.\n rdbms: Native relational-database connection — MySQL, PostgreSQL, MariaDB, Microsoft SQL Server, Azure Synapse, Oracle, Snowflake, Google BigQuery, Amazon Redshift (the database is `rdbms.type`).\n mongodb: MongoDB NoSQL database connection.\n as2: AS2 (Applicability Statement 2) EDI connection.\n filesystem: Local or network filesystem connection (requires an Agent).\n mcp: MCP (Model Context Protocol) server connection.\n dynamodb: Amazon DynamoDB NoSQL database connection.\n jdbc: JDBC connection for relational systems without a native `rdbms` type (Databricks, Db2, Workday, NetSuite JDBC) and for the driver-specific paths `jdbc.type` names (Oracle Thin, SQL Server with Active Directory); Redshift, BigQuery and Snowflake are `rdbms` types.\n van: Value-Added Network connection for EDI document exchange.\n rest: REST connection driven by a pre-built HTTP Connector template. Deprecated — use `http` instead.\n externalId:\n type: string\n description: External identifier for the connection, often used for integration with third-party systems\n examples: [\"erp-conn-001\"]\n assistant:\n type: string\n description: |\n Application name in lowercase for HTTP connections to systems with integrator.io adaptors.\n Used to identify the target application being connected to.\n Examples - Shopify: \"shopify\", eBay: \"ebay\".\n Only applicable for HTTP connection types.\n examples: [\"shopify\"]\n _agentId:\n type: string\n format: objectId\n x-celigo-refModel: agents\n description: |\n Reference to a Celigo on-premise Agent. Required for connection types that need\n local network or filesystem access (JDBC, filesystem, Oracle RDBMS, and on-premise MongoDB).\n The agent establishes a secure tunnel between the on-premise environment and integrator.io.\n examples: [\"5f8d43a1b9e5a80011a35f2c\"]\n _borrowConcurrencyFromConnectionId:\n type: string\n format: objectId\n x-celigo-refModel: connections\n description: |-\n Reference to another connection to share concurrency limits with. When set, this\n connection's traffic counts against the referenced connection's limit instead of its own,\n and its own concurrency and auto-recovery settings have no effect. One level only: the\n referenced connection may not itself borrow, and a connection that others borrow from\n cannot start borrowing. A connection cannot reference itself (422).\n examples: [\"615dfa0742763671275b70ab\"]\n x-celigo-ai-guidance:\n - |-\n Set this when several connections target one external account whose API enforces a\n single account-wide concurrency limit (for example one NetSuite account): put the limit\n on one parent connection and point the others here, so their combined traffic can never\n exceed it.\n - |-\n A borrower drains through the parent's queue as well as its ceiling, so a high-volume\n borrower competes with the parent's own flows — settle the priority split before\n choosing who borrows from whom.\n debugDate:\n type: string\n format: date-time\n description: Date until which debug logging is enabled for this connection\n examples: [\"2026-01-15T09:30:00.000Z\"]\n settingsForm:\n type: object\n description: Dynamic form configuration for connection-specific settings\n settings:\n type: object\n description: Connection-specific settings and configurations\n pgp:\n description: Present for file-based connections (ftp, s3, filesystem, …) that encrypt or decrypt files with PGP.\n allOf:\n - $ref: './pgp.yml#/PGP'\n ssl:\n $ref: './ssl.yml#/SSL'\n aiDescription:\n $ref: '../common-schemas/ai-description.yml#/AIDescription'\n offline:\n type: boolean\n description: |-\n When true, the connection has been taken offline and is skipped during flow execution.\n It is set by the connection test a create or `PUT` runs: the result arrives in the\n write's response or, when the target is slow to answer, shortly afterwards (the audit\n log records a `system` change; `lastModified` doesn't move), so read it again a few\n seconds after the write. On an `http` connection the write runs the test only when\n `http.ping` is configured, and an `http` connection that was never tested has no\n `offline` key.\n readOnly: true\n needsAuthorization:\n type: boolean\n readOnly: true\n description: |-\n OAuth handshake state. Celigo's OAuth callback sets it to `false` once the user consents\n and the tokens are stored (see `GET /v1/connection/{_id}/oauth2`). A connection that\n was never authorized usually has no `needsAuthorization` key, so its absence does not\n mean the connection is authorized.\n sandbox:\n type: boolean\n deprecated: true\n description: Whether this connection belongs to a sandbox environment.\n readOnly: true\n _sourceId:\n type: string\n format: objectId\n x-celigo-refModel: connections\n description: Source connection this was cloned from.\n readOnly: true\n examples: [\"5f29dbc69e8a0f0e29a491b7\"]\n connectionRole:\n type: string\n enum: [standard, mcpChild]\n x-enumDescriptions:\n standard: An ordinary account-owned connection, created and edited through this API\n mcpChild: An MCP end user's private credential copy of a parent connection, created by the end-user setup page\n readOnly: true\n description: |-\n Distinguishes account-owned connections from the per-end-user credential copies\n MCP servers collect. Absent on connections last saved before the field existed,\n which behave as `standard`. Sending `mcpChild` on `POST` or `PUT /v1/connections`\n fails with 422 `mcp_child_generic_route_not_allowed`, and `/connectionRole` is not a\n patchable path; child connections are written only by the MCP end-user setup page,\n never through `/v1`.\n examples: [standard]\n endUserProvidedFields:\n type: array\n items:\n type: string\n description: |-\n Dot-paths of this connection's fields (for example `http.encrypted.apiKey` or\n `rdbms.user`) that each MCP end user must supply on their own `mcpChild` copy instead\n of inheriting the parent's value. Only returned on a `standard` connection that has\n paths set; never returned on a child. Writable through `POST`, `PUT`, and `PATCH`;\n by the platform contract, a write that changes the list invalidates the children end\n users already hold against this parent.\n examples: [[\"http.encrypted.apiKey\", \"http.unencrypted.accountId\"]]\n _parentConnectionId:\n type: string\n format: objectId\n x-celigo-refModel: connections\n readOnly: true\n description: |-\n Parent connection this child copies its non-credential configuration from. Present\n only when `connectionRole` is `mcpChild`; set by the end-user setup page and ignored\n when sent on a standard connection.\n examples: [\"615dfa0742763671275b70ab\"]\n _mcpOwnerId:\n type: string\n format: objectId\n x-celigo-refModel: users\n readOnly: true\n description: |-\n Account owner whose parent connection and MCP servers this child belongs to. Present\n only when `connectionRole` is `mcpChild`; on a child, `_userId` is the end user and\n this field is the account.\n examples: [\"5d2e1f0a9b8c7d6e5f4a3b2c\"]\n _parentSyncedAt:\n type: string\n format: date-time\n readOnly: true\n description: |-\n Timestamp when the child's non-credential fields were last synced from the parent\n connection. Present only when `connectionRole` is `mcpChild`.\n examples: [\"2026-09-15T18:42:10.331Z\"]\n _userId:\n type: string\n format: objectId\n x-celigo-refModel: users\n description: |-\n End user who owns this `mcpChild` connection's credentials. Present only when\n `connectionRole` is `mcpChild`; a standard connection belongs to the account and\n omits this field.\n readOnly: true\n examples: [\"5d2e1f0a9b8c7d6e5f4a3b2c\"]\n debugUntil:\n type: string\n format: date-time\n description: Debug logging is active until this timestamp. Absent or in the past means debug is off.\n readOnly: true\n examples: [\"2026-01-15T09:30:00.000Z\"]\n encrypted:\n type: string\n description: Masked placeholder for encrypted credential fields. Always returns `\"******\"`.\n readOnly: true\n isHTTP:\n type: boolean\n description: When true, the connection uses the HTTP adaptor internally, even when `type` is `wrapper`.\n readOnly: true\n autoRecoverRateLimitErrors:\n type: boolean\n default: true\n description: |-\n When true, rate-limit errors from the target system trigger automatic recovery: concurrency\n drops to 1, the rate-limited requests are retried with doubling waits (1 to 1024 minutes,\n after which the flag switches itself off), and concurrency climbs back toward\n `targetConcurrencyLevel`. While true, `targetConcurrencyLevel` is the throughput lever: a\n `concurrencyLevel` sent in a PUT is ignored, and one sent in a PATCH is stored but the\n recovery machinery moves it back toward the target. Recovery never runs on `ftp`\n connections: FTP errors aren't treated as rate limits.\n x-celigo-ai-guidance:\n - To change throughput while this is true, write `targetConcurrencyLevel`; a `concurrencyLevel` sent in a PUT returns 200 and changes nothing.\n - Turning it on copies `concurrencyLevel` into `targetConcurrencyLevel`; turning it off unsets the target and leaves `concurrencyLevel` at its current value, which may be below the old target if a recovery was in progress. A `targetConcurrencyLevel` written while this is false is unset by the save.\n - These four settings (`concurrencyLevel`, `targetConcurrencyLevel`, `_borrowConcurrencyFromConnectionId`, this flag) accept a credential-free `PATCH /v1/connections/{_id}`. A PUT replaces the whole document, so send each secret back as its masked `******` value (that keeps it) or as a new value, and never drop one to keep it — an omitted password or `http.encrypted` is cleared, and a static token left out (with no `refreshMethod`) fails the PUT with 422.\n - On a create, while this is true, set the level with `targetConcurrencyLevel`: on `http`, `ftp`, `rdbms` and `mongodb` connections the save stores the target sent, or the adaptor's default without one (1 for `ftp`, 5 for `rdbms` and `mongodb`, 25 for `http` where the license's `concurrency` is at least 25), as both fields, whatever `concurrencyLevel` the body carried. A create that sends this as `false` keeps its `concurrencyLevel`.\n - On an `ftp` connection recovery never runs, and transfer threads are `ftp.multiThreadCount`.\n enableMicroBatchForOneToMany:\n type: boolean\n default: true\n description: When true, enables micro-batching for one-to-many data flows through this connection.\n enableCsvObjectParsing:\n type: boolean\n default: true\n description: When true, enables CSV-to-object parsing for data received through this connection.\n microServices:\n type: object\n description: Per-adaptor feature flags controlling which microservice workers handle this connection's traffic.\n readOnly: true\n properties:\n disableHttp:\n type: boolean\n description: When true, the HTTP microservice worker is disabled for this connection.\n disableNetSuiteDistributed:\n type: boolean\n description: When true, the NetSuite distributed-processing worker is disabled for this connection.\n disableNetSuiteProxy:\n type: boolean\n description: When true, the NetSuite proxy worker is disabled for this connection.\n disableNetSuiteWebservices:\n type: boolean\n description: When true, the NetSuite SuiteTalk Web Services worker is disabled for this connection.\n disableRdbms:\n type: boolean\n description: When true, the RDBMS worker is disabled for this connection.\n disableAs2:\n type: boolean\n description: When true, the AS2 worker is disabled for this connection.\n disableAs2File:\n type: boolean\n description: When true, the AS2 file-processing worker is disabled for this connection.\n disableDataLoaderFile:\n type: boolean\n description: When true, the data-loader file worker is disabled for this connection.\n disableFtp:\n type: boolean\n description: When true, the FTP worker is disabled for this connection.\n disableS3:\n type: boolean\n description: When true, the S3 worker is disabled for this connection.\n disableSalesforce:\n type: boolean\n description: When true, the Salesforce worker is disabled for this connection.\n disableFile:\n type: boolean\n description: When true, the generic file worker is disabled for this connection.\n disableNsFile:\n type: boolean\n description: When true, the NetSuite file worker is disabled for this connection.\n workerGroup:\n type: string\n description: Name of the worker group that processes this connection's traffic.\n examples: [\"default\"]\n queues:\n type: array\n description: Message queue sizes for this connection. Always present on GET-by-ID; on the list endpoint only when `fetchQueueSize=true`.\n readOnly: true\n items:\n type: object\n properties:\n name:\n type: string\n description: Queue identifier (typically the connection ID).\n examples: [\"615dfa0742763671275b70ab\"]\n size:\n type: integer\n description: Number of messages currently in the queue.\n examples: [0]\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":16882,"content_sha256":"12a6fea01d779f9e79b5dfdc48640aa5fbe4612b69dfd02e72b24d4f7eb20178"},{"filename":"references/schemas/response.yml","content":"Connection:\n type: object\n required:\n - _id\n - name\n - type\n - createdAt\n - lastModified\n description: Connection object as returned by the API.\n allOf:\n - $ref: './response-base.yml#/ResponseBase'\n - type: object\n properties:\n netsuite:\n description: Present when `type` is `netsuite`.\n allOf:\n - $ref: './netsuite.yml#/NetSuite'\n - type: object\n properties:\n suiteAppInstalled:\n type: boolean\n readOnly: true\n description: |-\n When true, the Celigo integrator.io SuiteApp (SuiteScript 2.x) was detected in\n the connected NetSuite account the last time the connection authenticated. It\n says nothing about the legacy Celigo bundle; for a live check of both, use\n `GET /v1/connections/{_id}/distributedApps`.\n salesforce:\n description: Present when `type` is `salesforce`.\n allOf:\n - $ref: './salesforce.yml#/Salesforce'\n - type: object\n properties:\n info:\n type: object\n readOnly: true\n description: |-\n Salesforce org and user metadata populated by the server after a successful\n authentication (the OpenID Connect userinfo of the authorizing user). Read-only.\n properties:\n user_id:\n type: string\n readOnly: true\n description: Salesforce user ID of the authorizing user.\n examples:\n - 00536000000vNR3AAM\n organization_id:\n type: string\n readOnly: true\n description: Salesforce organization (org) ID this connection authenticates to.\n examples:\n - 00D36000000ZtDMEA0\n email:\n type: string\n format: email\n readOnly: true\n description: Email address of the authorizing Salesforce user.\n examples:\n - [email protected]\n preferred_username:\n type: string\n readOnly: true\n description: Salesforce login username of the authorizing user.\n examples:\n - [email protected]\n name:\n type: string\n readOnly: true\n description: Full display name of the authorizing user.\n examples:\n - Integration User\n is_salesforce_integration_user:\n type: boolean\n readOnly: true\n description: When true, the authorizing user is a Salesforce Integration User license.\n ftp:\n description: Present when `type` is `ftp`.\n allOf:\n - $ref: './ftp.yml#/FTP'\n s3:\n description: Present when `type` is `s3`.\n allOf:\n - $ref: './s3.yml#/S3'\n http:\n description: Present when `type` is `http`.\n allOf:\n - $ref: './http.yml#/HTTP'\n rdbms:\n description: Present when `type` is `rdbms`.\n allOf:\n - $ref: './rdbms.yml#/RDBMS'\n mongodb:\n description: Present when `type` is `mongodb`.\n allOf:\n - $ref: './mongodb.yml#/MongoDB'\n as2:\n description: Present when `type` is `as2`.\n allOf:\n - $ref: './as2.yml#/AS2'\n filesystem:\n description: Present when `type` is `filesystem`.\n allOf:\n - $ref: './filesystem.yml#/Filesystem'\n mcp:\n description: Present when `type` is `mcp`.\n allOf:\n - $ref: './mcp.yml#/MCP'\n dynamodb:\n description: Present when `type` is `dynamodb`.\n allOf:\n - $ref: './dynamodb.yml#/DynamoDB'\n jdbc:\n description: Present when `type` is `jdbc`.\n allOf:\n - $ref: './jdbc.yml#/JDBC'\n van:\n description: Present when `type` is `van`.\n allOf:\n - $ref: './van.yml#/VAN'\n wrapper:\n description: Present when `type` is `wrapper`.\n allOf:\n - $ref: './wrapper.yml#/Wrapper'\n rest:\n deprecated: true\n description: Present when `type` is `rest`. Deprecated — superseded by `http` with a pre-built HTTP Connector template.\n allOf:\n - $ref: './rest.yml#/REST'\n # The active type's config object is present and required for that type. Nested if/else-if\n # (no allOf), sibling of the composition allOf above — stack-style.\n if: { properties: { type: { const: netsuite } }, required: [type] }\n then: { required: [netsuite] }\n else:\n if: { properties: { type: { const: salesforce } }, required: [type] }\n then: { required: [salesforce] }\n else:\n if: { properties: { type: { const: ftp } }, required: [type] }\n then: { required: [ftp] }\n else:\n if: { properties: { type: { const: s3 } }, required: [type] }\n then: { required: [s3] }\n else:\n if: { properties: { type: { const: http } }, required: [type] }\n then: { required: [http] }\n else:\n if: { properties: { type: { const: rdbms } }, required: [type] }\n then: { required: [rdbms] }\n else:\n if: { properties: { type: { const: mongodb } }, required: [type] }\n then: { required: [mongodb] }\n else:\n if: { properties: { type: { const: as2 } }, required: [type] }\n then: { required: [as2] }\n else:\n if: { properties: { type: { const: filesystem } }, required: [type] }\n then: { required: [filesystem] }\n else:\n if: { properties: { type: { const: mcp } }, required: [type] }\n then: { required: [mcp] }\n else:\n if: { properties: { type: { const: dynamodb } }, required: [type] }\n then: { required: [dynamodb] }\n else:\n if: { properties: { type: { const: jdbc } }, required: [type] }\n then: { required: [jdbc] }\n else:\n if: { properties: { type: { const: van } }, required: [type] }\n then: { required: [van] }\n else:\n if: { properties: { type: { const: wrapper } }, required: [type] }\n then: { required: [wrapper] }\n else:\n if: { properties: { type: { const: rest } }, required: [type] }\n then: { required: [rest] }\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":7218,"content_sha256":"e4482404d6e7434cfff93744c241631f47877c17393541d1543fd55918861ae1"},{"filename":"references/schemas/rest.yml","content":"REST:\n type: object\n deprecated: true\n description: |\n **Deprecated.** The `rest` connection type is superseded by `http` with a pre-built HTTP\n Connector template; new connections should use `http`. This schema documents the legacy\n `rest` connection type for connections that still use it.\n\n Configuration for REST connector connections. Used when the connection type is \"rest\".\n\n REST connections are template-driven HTTP connections that use a pre-built HTTP Connector\n definition. The connector template pre-configures authentication, base URI, and other\n settings — the user only fills in credentials and account-specific values.\n\n **Rest vs http connections**\n - Use \"rest\" when connecting to an application that has a Celigo HTTP Connector template\n (referenced via _httpConnectorId). The connector provides pre-configured API settings.\n - Use \"http\" for fully custom API connections where you configure everything manually.\n\n **Authentication**\n The authType field selects the authentication method. Available methods depend on the\n connector template. Credentials are stored in the appropriate auth sub-fields (basicAuth,\n bearerToken, refreshToken, oauth, etc.).\n required:\n - mediaType\n - baseURI\n - authType\n properties:\n mediaType:\n type: string\n enum:\n - json\n - urlencoded\n - xml\n - csv\n x-enumDescriptions:\n json: Serialize request and response bodies as application/json.\n urlencoded: Serialize request bodies as application/x-www-form-urlencoded.\n xml: Serialize request and response bodies as application/xml.\n csv: Serialize request and response bodies as text/csv.\n description: |-\n Default content type for API requests and responses.\n Most REST connector templates default to json.\n x-lowercase: true\n baseURI:\n type: string\n description: |\n Base URL for all API requests. REQUIRED.\n All relative URIs in exports and imports are appended to this base URL.\n May be pre-populated by the HTTP Connector template, and may contain\n Handlebars expressions (e.g. a `{{{connection.settings.subdomain}}}` segment).\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n authType:\n type: string\n enum:\n - basic\n - token\n - oauth\n - custom\n - cookie\n - jwt\n - hmac\n - wsse\n - oauth1\n x-enumDescriptions:\n basic: HTTP Basic Authentication using a username and password.\n token: Bearer token or API key with optional automatic refresh.\n oauth: OAuth 2.0 authentication with authorization code, client credentials, or password grant.\n custom: No built-in auth; credentials are placed in headers or encrypted fields.\n cookie: Cookie-based session authentication via a login endpoint.\n jwt: JWT-based authentication with configurable signing.\n hmac: HMAC signature authentication for request signing.\n wsse: WS-Security UsernameToken authentication for SOAP APIs.\n oauth1: OAuth 1.0a authentication with HMAC or RSA signatures.\n description: |-\n Authentication method for this connection. Available methods depend on\n the connector template. Each type requires specific credential sub-fields.\n x-lowercase: true\n authURI:\n type: string\n description: |\n OAuth 2.0 authorization endpoint URI.\n Used for OAuth authorization code flow where users authorize via browser.\n format: uri\n oauthTokenURI:\n type: string\n description: |\n OAuth 2.0 token endpoint URI.\n Used to exchange authorization codes for access tokens and to refresh tokens.\n format: uri\n disableStrictSSL:\n type: boolean\n description: |\n When true, disables strict SSL/TLS certificate validation.\n Only use for development/testing with self-signed certificates.\n default: false\n skipOauthValidations:\n type: boolean\n description: |\n When true, skips Celigo's built-in OAuth configuration validation.\n Use when the connector has non-standard OAuth requirements.\n default: false\n isHTTPProxy:\n type: boolean\n description: |\n When true, this REST connection acts as an HTTP proxy for another connection.\n default: false\n authHeader:\n type: string\n description: |\n Custom HTTP header name for the authorization token.\n Defaults to \"Authorization\". Change only if the API uses a non-standard header.\n default: \"Authorization\"\n retryHeader:\n type: string\n description: |\n HTTP response header name containing retry-after delay for rate-limited requests.\n Defaults to \"Retry-After\" (HTTP standard).\n default: \"Retry-After\"\n authScheme:\n type: string\n enum:\n - MAC\n - OAuth\n - Bearer\n - Hmac\n - \" \"\n x-celigo-deprecated-enum-values:\n - \" \"\n x-enumDescriptions:\n MAC: Use the MAC (Message Authentication Code) authorization scheme.\n OAuth: Use the OAuth authorization scheme prefix.\n Bearer: Use the Bearer token authorization scheme (most common).\n Hmac: Use the HMAC authorization scheme for signed requests.\n \" \": \"Deprecated: a single space sends the token with no scheme prefix (stored by legacy connector templates).\"\n description: |\n Authorization header scheme/prefix prepended before the token value.\n Produces headers like \"Authorization: Bearer \u003ctoken>\".\n Defaults to \"Bearer\" which is the most common scheme.\n default: Bearer\n scope:\n type: array\n items:\n type: string\n description: |\n OAuth scopes to request during authorization. Controls the level of API access granted.\n scopeDelimiter:\n type: string\n description: |\n Delimiter character between multiple OAuth scopes.\n Defaults to a space (\" \") per the OAuth 2.0 spec. Some APIs use commas.\n default: \" \"\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent API requests.\n Set based on the target API's rate limit documentation.\n minimum: 1\n maximum: 100\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |\n Target concurrency level for auto-scaling. The system adjusts concurrency\n between 1 and this value based on rate limit feedback.\n minimum: 1\n maximum: 100\n bearerToken:\n type: string\n description: |\n Bearer token or API key for authentication (encrypted at rest).\n Used when authType is \"token\".\n writeOnly: true\n refreshToken:\n type: string\n description: |\n OAuth refresh token (encrypted at rest).\n Used to obtain new access tokens when they expire.\n writeOnly: true\n tokenLocation:\n type: string\n enum:\n - header\n - url\n x-enumDescriptions:\n header: Send the access token in the Authorization header.\n url: Send the access token as a URL query parameter.\n description: |-\n Where to include the access token in outbound requests.\n Defaults to header. Use tokenParam to set the query parameter name when sending via url.\n default: header\n tokenParam:\n type: string\n description: |\n URL query parameter name for the access token when tokenLocation is \"url\".\n default: access_token\n basicAuth:\n type: object\n description: |\n Basic authentication credentials. REQUIRED when authType is \"basic\" or \"wsse\".\n properties:\n username:\n type: string\n description: Username for Basic authentication.\n password:\n type: string\n description: Password for Basic authentication (encrypted at rest).\n writeOnly: true\n cookieAuth:\n type: object\n description: |\n Cookie-based session authentication configuration.\n REQUIRED when authType is \"cookie\".\n properties:\n uri:\n type: string\n description: |-\n Login endpoint URI. REQUIRED. The system sends a request here to obtain session cookies.\n\n Use an HTTPS URL whenever possible. HTTP is not considered a secure protocol; data sent\n to an HTTP endpoint is not encrypted and may be intercepted or modified in transit.\n body:\n type: string\n description: Request body for the login request (e.g., JSON with credentials).\n method:\n type: string\n description: HTTP method for the login request (typically POST).\n successStatusCode:\n type: number\n description: HTTP status code that confirms successful authentication.\n oauth:\n $ref: './oauth.yml#/OAuth'\n refreshTokenMethod:\n type: string\n enum:\n - POST\n - PUT\n - GET\n x-enumDescriptions:\n POST: Use a POST request to refresh the token.\n PUT: Use a PUT request to refresh the token.\n GET: Use a GET request to refresh the token.\n description: |\n HTTP method for token refresh requests.\n default: POST\n x-uppercase: true\n refreshTokenBody:\n type: string\n description: Request body template for token refresh requests.\n refreshTokenURI:\n type: string\n description: URI for the token refresh endpoint.\n format: uri\n refreshTokenPath:\n type: string\n description: |\n JSON path to extract the new access token from the refresh response.\n Example: \"access_token\" or \"data.token\".\n refreshTokenMediaType:\n type: string\n enum:\n - json\n - urlencoded\n x-enumDescriptions:\n json: Send the refresh request body as application/json.\n urlencoded: Send the refresh request body as application/x-www-form-urlencoded.\n description: Content type for token refresh request bodies.\n default: json\n x-lowercase: true\n refreshTokenHeaders:\n type: array\n description: Additional headers to include in token refresh requests.\n items:\n type: object\n properties:\n name:\n type: string\n value:\n type: string\n required:\n - name\n - value\n headers:\n type: array\n description: |\n Default HTTP headers included in every API request.\n Use for API keys in custom headers, content negotiation, or required headers.\n items:\n type: object\n properties:\n name:\n type: string\n description: Header name.\n value:\n type: string\n description: Header value. Supports handlebars expressions.\n required:\n - name\n - value\n pingRelativeURI:\n type: string\n description: |\n Relative URI (appended to baseURI) for connection health check requests.\n Should be a lightweight endpoint (e.g., \"/me\", \"/health\").\n pingSuccessPath:\n type: string\n description: |\n JSON path to extract a success indicator from the ping response.\n If the value matches one of pingSuccessValues, the ping succeeds.\n pingSuccessValues:\n type: array\n items:\n type: string\n description: Values that indicate a successful ping at pingSuccessPath.\n pingFailurePath:\n type: string\n description: |\n JSON path to extract a failure indicator from the ping response.\n pingFailureValues:\n type: array\n items:\n type: string\n description: Values that indicate a failed ping at pingFailurePath.\n pingMethod:\n type: string\n enum:\n - GET\n - POST\n x-enumDescriptions:\n GET: Send a GET request to the ping endpoint.\n POST: Send a POST request to the ping endpoint.\n description: HTTP method for ping requests.\n default: GET\n x-uppercase: true\n pingBody:\n type: string\n description: Request body for ping requests (when pingMethod is POST).\n encrypted:\n type: [object, string]\n description: |\n Encrypted custom fields for sensitive configuration values.\n Field definitions are in encryptedFields. Send an object when\n writing; API responses mask the whole value as the string `\"******\"`.\n encryptedFields:\n type: array\n description: Metadata defining the encrypted custom fields on this connection.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the encrypted object.\n label:\n type: string\n description: Human-readable label shown in the UI.\n required:\n type: boolean\n default: false\n position:\n type: number\n description: Display order in the UI form.\n helpText:\n type: string\n description: Tooltip text shown next to the field in the UI.\n unencrypted:\n type: object\n description: |\n Unencrypted custom fields for non-sensitive configuration values.\n Field definitions are in unencryptedFields.\n unencryptedFields:\n type: array\n description: Metadata defining the unencrypted custom fields on this connection.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the unencrypted object.\n label:\n type: string\n description: Human-readable label shown in the UI.\n required:\n type: boolean\n default: false\n position:\n type: number\n description: Display order in the UI form.\n helpText:\n type: string\n description: Tooltip text shown next to the field in the UI.\n type:\n type: string\n description: Field type hint for the UI (e.g., \"text\", \"select\").\n info:\n type: object\n description: Additional metadata about the REST connection, populated by the system.\n readOnly: true\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":14468,"content_sha256":"1453d1e4b98742ff4c47bbcc5c9fbcc6814f8ddc2e8cbe2009a260abe39857d9"},{"filename":"references/schemas/s3.yml","content":"S3:\n type: object\n description: |-\n Configuration for Amazon S3 connections. Used when the connection type is \"s3\". Provides\n upload, download, list, and delete access to S3 buckets. Authenticate with a static IAM\n access key pair (authType `accesskey`) or by referencing an iClient that holds AWS IAM role\n credentials (authType `awsIam`). Set pingBucket to an accessible bucket so Celigo can validate\n the credentials.\n properties:\n authType:\n type: string\n enum:\n - accesskey\n - awsIam\n default: accesskey\n x-enumDescriptions:\n accesskey: Authenticate with a static IAM access key pair (accessKeyId + secretAccessKey).\n awsIam: Authenticate with AWS IAM role credentials supplied by a referenced iClient (_iClientId).\n description: |-\n Authentication method for the S3 bucket. Defaults to `accesskey` when omitted. Use `awsIam`\n to delegate authentication to an iClient that holds an AWS IAM role instead of embedding a\n static key pair.\n examples: [\"accesskey\"]\n accessKeyId:\n type: string\n description: |-\n AWS access key ID for IAM authentication. From an IAM user or role with S3 permissions\n (s3:GetObject, s3:PutObject, s3:ListBucket, etc.). Used when authType is `accesskey`.\n examples: [\"AKIA_EXAMPLE_KEY_ID\"]\n x-celigo-ui-override: >-\n The connection form marks accessKeyId required when Auth type is \"Access key & secret\"\n (`accesskey`) and removes it when Auth type is \"IAM role\" (`awsIam`). The API enforces it\n for authType `accesskey` (POST without it returns 422 missing_required_field) — encoded\n via the if/then/else rule below.\n secretAccessKey:\n type: string\n writeOnly: true\n description: AWS secret access key, paired with accessKeyId. Used when authType is `accesskey`. Encrypted at rest; returned masked as `\"******\"`.\n examples: [\"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"]\n x-celigo-ui-override: >-\n The connection form marks secretAccessKey required when Auth type is \"Access key & secret\"\n (`accesskey`) and removes it when Auth type is \"IAM role\" (`awsIam`). The API enforces it\n for authType `accesskey` (POST without it returns 422 missing_required_field) — encoded via\n the if/then/else rule below.\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n description: |-\n Reference to an iClient that holds AWS IAM role credentials. Required when authType is\n `awsIam`; ignored otherwise. The iClient must carry `awsIam.roleArn`, and that role's name\n must start with `celigo-file-adaptor-` — the S3 service assumes only roles in that family,\n so a role created for an HTTP or Redshift connection cannot be reused here.\n examples: [\"65f99e3e6b5b420fea998454\"]\n x-celigo-ai-guidance:\n - When authType is \"awsIam\", set _iClientId to an existing iClient; omitting it fails the POST with 422 \"Expected field: _iClientId to be present.\"\n - The referenced iClient must itself be an awsIam-provider iClient; referencing any other iClient fails the POST with 422 \"IClient provider must be awsIam for S3 IAM Role authentication.\"\n - |-\n The referenced iClient must have awsIam.roleArn set (otherwise 422 missing_required_field on\n s3._iClientId \"Expected field: awsIam.roleArn to be present.\") and its role name must start\n with \"celigo-file-adaptor-\" (otherwise 422 invalid_field_value on s3._iClientId \"Invalid\n value for field \\\"_iClientId\\\": Your role ARN's name must begin with celigo-file-adaptor.\").\n Point an S3 connection at an iClient whose role was named for S3; do not reuse a\n celigo-http-adaptor- or celigo-data-warehouse-adaptor- role.\n - |-\n With authType \"awsIam\", omit accessKeyId and secretAccessKey — the API does not reject\n them, it stores them alongside the iClient reference, leaving a stray static credential\n on a connection that no longer uses one.\n pingBucket:\n type: string\n description: |-\n S3 bucket name used for connection health checks (ping). The system performs a HEAD request\n on this bucket to verify credentials. Must be a bucket the credentials have access to.\n examples: [\"my-data-lake\"]\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of concurrent S3 operations. Applies when `autoRecoverRateLimitErrors` is\n false; when auto-recover is on (the default) concurrency auto-scales up to\n `targetConcurrencyLevel` and a `concurrencyLevel` sent on its own is reconciled back. Send no\n more than the account's licensed maximum.\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |-\n Upper bound for auto-scaled concurrency when `autoRecoverRateLimitErrors` is true (the\n default). The system raises and lowers concurrency between 1 and this value based on\n rate-limit feedback from S3.\n minimum: 1\n maximum: 50\n default: 5\n _tpConnectorId:\n type: string\n format: objectId\n x-celigo-refModel: tradingpartnerconnectors\n description: |-\n Trading partner connector this S3 connection was provisioned from during partner\n onboarding. Stored and returned here, under `s3`, like `ftp._tpConnectorId` and\n `as2._tpConnectorId` on the other partner transports; a top-level `_tpConnectorId` on\n the connection body is not stored. Omit for a standalone S3 connection.\n examples: [\"66a1b2c3d4e5f60718293a4b\"]\n # Conditional requireds are both API-verified (422 missing_required_field) and mirror the\n # connection form (see x-celigo-ui-override). Stack-style top-level if/then/else; GitBook ignores\n # it, downstream consumers get accurate validation.\n # Rule: awsIam needs _iClientId; accesskey (and the default, absent authType) need accessKeyId + secretAccessKey.\n if:\n properties:\n authType:\n const: awsIam\n required: [authType]\n then:\n required: [_iClientId]\n else:\n required: [accessKeyId, secretAccessKey]\n x-celigo-ai-guidance:\n - |-\n Provides access to Amazon S3 buckets for file-based integrations (upload, download,\n list, and delete operations). Uses AWS IAM credentials for authentication.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":6468,"content_sha256":"0d6038334caec30cc3d65c9dfd21cf8f25c87a36b63823de5eba1f8928c3c0e8"},{"filename":"references/schemas/salesforce.yml","content":"Salesforce:\n type: object\n description: |-\n Configuration for Salesforce CRM connections. Used when the connection type is \"salesforce\".\n Authenticates via OAuth 2.0: oauth2FlowType \"jwtBearerToken\" does server-to-server auth\n through a Connected App (recommended for automation), while \"refreshToken\" uses an\n interactive browser authorization for user-context integrations.\n required:\n - oauth2FlowType\n - sandbox\n x-celigo-ui-override: >-\n oauth2FlowType and sandbox are required by the connection form (the API itself accepts a\n connection without either — both were live-verified to POST 201 when omitted, defaulting to\n refreshToken and false). The jwtBearerToken flow additionally requires username (see the\n if/then below). The refreshToken flow does not require refreshToken here — it is obtained via\n the OAuth authorization flow, not entered in the form. Encoded to mirror the form so builders\n produce connectable connections.\n properties:\n sandbox:\n type: boolean\n description: |-\n Whether this connection targets a Salesforce non-production (sandbox) org. When true,\n authenticates against test.salesforce.com instead of login.salesforce.com. Must match\n the actual Salesforce org type or authentication fails. This is the form's\n production-vs-sandbox selector (distinct from the connection-level `sandbox` flag).\n default: false\n x-celigo-ai-guidance:\n - |-\n - true — Uses test.salesforce.com for authentication.\n - false — Uses login.salesforce.com for authentication (production).\n oauth2FlowType:\n type: string\n enum:\n - jwtBearerToken\n - refreshToken\n x-enumDescriptions:\n jwtBearerToken: Server-to-server JWT Bearer Token flow; requires a Connected App with a digital certificate and the username field.\n refreshToken: Authorization Code / Refresh Token flow; requires initial browser-based authorization, then the refresh token for ongoing access.\n description: |-\n OAuth 2.0 authentication flow type. Use jwtBearerToken for automated server-to-server\n integrations (requires a Connected App with a digital certificate and the username field).\n Use refreshToken for integrations that operate in a specific user's context. Defaults to\n refreshToken when omitted.\n default: refreshToken\n examples:\n - refreshToken\n username:\n type: string\n description: |-\n Salesforce login username (email) of the user whose permissions the integration operates\n under. Used by the jwtBearerToken flow to identify the subject of the assertion.\n x-celigo-ui-override: >-\n Required by the connection form when oauth2FlowType is jwtBearerToken (the form hides this\n field for the refreshToken flow). The API enforces neither the requirement nor the flow\n gating — it stores username whenever sent.\n examples:\n - [email protected]\n x-celigo-ai-guidance:\n - |-\n Salesforce username for JWT Bearer Token authentication.\n REQUIRED when oauth2FlowType is \"jwtBearerToken\".\n _iClientId:\n type: string\n format: objectId\n x-celigo-refModel: iclients\n description: |-\n Reference to the iClient holding your own Salesforce Connected App's client ID and secret.\n Set this to authenticate through a custom Connected App; omit it to use Celigo's\n pre-configured Connected App.\n examples:\n - 5f4414102aeb686432f8e71a\n baseURI:\n type: string\n format: uri\n description: |-\n Salesforce instance URL for this org (e.g. \"https://mycompany.my.salesforce.com\").\n Auto-discovered and populated during OAuth authentication; set it explicitly only to\n force a specific instance URL.\n examples:\n - https://mycompany.my.salesforce.com\n x-celigo-ai-guidance:\n - |-\n Normally auto-discovered during OAuth authentication. Only set this to\n force a specific instance URL (e.g., \"https://mycompany.my.salesforce.com\").\n bearerToken:\n type: string\n writeOnly: true\n description: |-\n OAuth access token for Salesforce API calls (encrypted at rest; returned masked as\n `\"******\"`). Auto-managed by the system during the OAuth flow; rarely set manually.\n examples:\n - \u003corg-id>!\u003csession-token>\n x-celigo-ai-guidance:\n - |-\n OAuth access/bearer token (encrypted at rest).\n Typically auto-managed by the system during OAuth flows. Rarely set manually.\n refreshToken:\n type: string\n writeOnly: true\n description: |-\n OAuth refresh token used to mint new access tokens (encrypted at rest; returned masked as\n `\"******\"`). Obtained during the initial browser-based authorization of the refreshToken\n flow; auto-managed by the system.\n examples:\n - 5Aep861[fake-refresh-token]xyz\n x-celigo-ai-guidance:\n - |-\n OAuth refresh token (encrypted at rest). REQUIRED when oauth2FlowType is \"refreshToken\".\n Obtained during the initial browser-based OAuth authorization flow.\n packagedOAuth:\n type: boolean\n description: |-\n When true, the connection uses Celigo's pre-configured (packaged) Connected App. Set by\n the system based on whether a custom `_iClientId` is supplied and the OAuth flow completed;\n not reliably honored when supplied in the request body.\n x-celigo-ai-guidance:\n - |-\n When true, uses Celigo's pre-configured Connected App for OAuth.\n When false, you must provide your own Connected App credentials via iClient.\n scope:\n type: array\n items:\n type: string\n description: |-\n OAuth scopes requested during authorization. Scope values are defined by Salesforce — `full`\n grants complete API access and `refresh_token` enables long-lived refresh tokens. Defaults\n to `full` and `refresh_token` when omitted. A saved empty array is the normal stored state:\n the connection form does not expose this field, and every save from the connection editor\n resets values written through the API.\n default: [\"full\", \"refresh_token\"]\n examples:\n - [\"full\", \"refresh_token\"]\n x-celigo-ai-guidance:\n - >-\n Never set or repair this field to fix an authentication failure: an empty or absent\n list is the normal stored state, and UI saves reset API-written values.\n - >-\n For a custom Connected App (`salesforce._iClientId` set), requested scopes are\n configured on the iClient's `oauth2.scope` and constrained by the Connected App\n inside Salesforce — not on the connection.\n concurrencyLevel:\n type: integer\n description: |-\n Maximum number of concurrent API requests to Salesforce. Salesforce enforces per-org API\n request limits, so setting this high consumes the org's API call allocation faster. Send no\n more than the account's licensed ceiling.\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |-\n Upper bound for auto-scaling concurrency. When automatic rate-limit recovery is enabled, the\n system adjusts concurrency between 1 and this value based on rate-limit feedback from\n Salesforce. Send no more than the account's licensed ceiling.\n minimum: 1\n maximum: 50\n default: 5\n x-celigo-ui-override: >-\n Required by the connection form, but only shown (and only applicable) when\n autoRecoverRateLimitErrors is true and no concurrency is borrowed from another connection.\n The API does not enforce it and defaults it to 5.\n # jwtBearerToken flow requires username (connection form rule) — top-level if/then, no allOf.\n if:\n properties:\n oauth2FlowType:\n const: jwtBearerToken\n required:\n - oauth2FlowType\n then:\n required:\n - username\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":8130,"content_sha256":"6910b6524e1723381ce0274dcaf362d3cb9e6b8d32fc72d8dde00c05dc991cff"},{"filename":"references/schemas/ssl.yml","content":"SSL:\n type: object\n description: |-\n SSL/TLS certificate configuration for database connections that use client certificate\n (mTLS) authentication or connect to servers with private CA-signed certificates. Provide\n cert and key together for mTLS, ca for a private CA, and passphrase only when the private\n key is encrypted; cert/key and ca can be combined.\n properties:\n ca:\n type: string\n description: |-\n Certificate Authority certificate in PEM format. Set when the database server uses a\n certificate signed by a private CA not in the system's default trust store.\n writeOnly: true\n key:\n type: string\n description: |-\n Client private key in PEM format, paired with cert for mTLS authentication.\n Cannot be provided without cert.\n writeOnly: true\n passphrase:\n type: string\n description: Passphrase that decrypts the private key in the key field, when that key is password-protected.\n writeOnly: true\n examples:\n - \"client-key-passphrase-EXAMPLE\"\n x-celigo-ai-guidance:\n - |-\n Passphrase to decrypt an encrypted private key (encrypted at rest).\n Only needed when the PEM private key in the key field is password-protected.\n cert:\n type: string\n description: |-\n Client certificate in PEM format, paired with key for mTLS authentication.\n Cannot be provided without key.\n writeOnly: true\n x-celigo-ai-guidance:\n - |-\n Used by RDBMS and other connection types that support client certificate authentication\n or connections to servers with private CA-signed certificates.\n\n ## USAGE RULES\n - Provide cert + key together for client certificate (mutual TLS) authentication.\n - Provide ca alone when the server uses a certificate signed by a private CA.\n - cert/key and ca can be combined for mTLS with a private CA.\n - passphrase is only needed when the private key is encrypted.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":1989,"content_sha256":"d62865a130f06adb4964abfce4f893dce848263516fff4c81cd831a71a5a230d"},{"filename":"references/schemas/van.yml","content":"VAN:\n type: object\n description: |-\n Configuration for VAN (Value-Added Network) connections. Used when the connection type is \"van\".\n A VAN connection exchanges EDI documents through a managed network mailbox; outbound documents are\n posted to the mailbox and inbound documents are picked up from it, addressed by the connection's AS2 identifier.\n properties:\n as2Id:\n type: string\n description: |-\n AS2 identifier for this VAN station — the \"From\" identifier on outbound documents and the \"To\"\n identifier on inbound. Must be unique across all integrator.io VAN connections; a duplicate fails\n the create. Set once when the connection is created and cannot be changed afterward (writes on update\n are ignored). Omit it to have the network assign one automatically.\n examples: [\"AcmeFoods_VAN01\"]\n x-celigo-ai-guidance:\n - |-\n AS2 identifier for this VAN station. Used as the \"From\" identifier when sending\n documents and the \"To\" identifier when receiving. Must be unique across all\n integrator.io users. Cannot be changed after creation.\n mailboxId:\n type: number\n readOnly: true\n description: |-\n Numeric mailbox identifier assigned by the VAN provider when the connection is provisioned.\n Server-assigned and not writable — values sent on create or update are ignored.\n examples: [609973178]\n x-celigo-ai-guidance:\n - |-\n VAN mailbox identifier. Identifies the specific mailbox on the VAN provider\n that this connection sends to and receives from.\n contentBasedFlowRouter:\n type: object\n description: |-\n Routes inbound documents to different flows based on message content, for a connection shared across\n multiple flows. The named function in the referenced script inspects each incoming document and returns\n the flow to run. Omit to disable content-based routing.\n properties:\n function:\n type: string\n description: Function in the referenced script that returns the target flow for each inbound document.\n examples: [\"contentBasedFlowRouter\"]\n _scriptId:\n type: string\n format: objectId\n x-celigo-refModel: scripts\n description: ID of the script resource that contains the routing function. Must reference an existing script; an unknown ID fails the request with 422 `invalid_ref`.\n examples: [\"67642324b29f4856c6865f7c\"]\n x-celigo-ai-guidance:\n - |-\n Content-based routing configuration for inbound VAN documents.\n Routes incoming documents to different flows based on document content\n using a custom JavaScript function.\n x-celigo-ai-guidance:\n - |-\n VAN connections provide EDI document exchange through a Value Added Network provider.\n Documents are sent to and received from a VAN mailbox identified by the mailboxId.\n\n The as2Id field links this VAN connection to an AS2 identity for document routing,\n and contentBasedFlowRouter enables routing inbound documents to different flows\n based on document content.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":3189,"content_sha256":"24a1dbcebd0f29570d4626e946ad0a88a742cffecbd88fd169917fe4e39cde7b"},{"filename":"references/schemas/wrapper.yml","content":"Wrapper:\n type: object\n description: |-\n Configuration for Wrapper connections. Used when the connection type is \"wrapper\". A wrapper\n is a fully custom connector implemented in server-side JavaScript on a Celigo Stack\n (referenced by _stackId) — use it when the target API needs\n non-standard authentication or logic that HTTP connections can't express. Connection-specific\n values go in the encrypted/unencrypted fields, which the wrapper code reads at runtime.\n required:\n - pingFunction\n properties:\n pingFunction:\n type: string\n description: |-\n Name of the JavaScript function on the Stack that tests connection health, invoked when\n \"Test Connection\" is clicked. It should verify the credentials are valid and the target\n system is reachable.\n x-celigo-ui-override: >-\n Required by the connection form for standalone wrappers. The form hides it for\n connector-managed wrappers (when _connectorId is set), where the connector supplies it.\n examples: [\"ping\"]\n x-celigo-ai-guidance:\n - |-\n Name of the JavaScript function on the Stack that tests connection health.\n This function is called when the user clicks \"Test Connection\" in the UI.\n It should verify that the connection credentials are valid and the target\n system is reachable.\n unencrypted:\n type: object\n description: |\n Unencrypted custom fields for non-sensitive configuration values.\n These values are accessible to the wrapper code on the Stack at runtime.\n Field definitions are specified in unencryptedFields.\n examples:\n - {accountId: \"ACME-42891\", region: \"us-west\"}\n unencryptedFields:\n type: array\n description: Metadata defining the unencrypted custom fields on this connection.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the unencrypted object.\n examples: [\"accountId\"]\n label:\n type: string\n description: Human-readable label shown in the UI.\n examples: [\"Account ID\"]\n required:\n type: boolean\n default: false\n description: When true, the custom field defined by this entry is mandatory — a value for it must be supplied before the connection can be saved.\n position:\n type: number\n description: Display order in the UI form.\n examples: [1]\n helpText:\n type: string\n description: Tooltip text shown next to the field in the UI.\n examples: [\"Your vendor account identifier.\"]\n type:\n type: string\n description: |-\n Optional, legacy field-type hint. The wrapper form ignores it — it always renders these\n custom fields as text inputs — so it is rarely set.\n encrypted:\n type:\n - object\n - string\n description: |\n Encrypted custom fields for sensitive configuration values (API keys, passwords, etc.).\n Sent as an object of field-name/value pairs; values are encrypted at rest and decrypted\n only on the Stack at runtime. Returned as the masked string `\"******\"` on responses.\n Field definitions are specified in encryptedFields.\n encryptedFields:\n type: array\n description: Metadata defining the encrypted custom fields on this connection.\n items:\n type: object\n properties:\n id:\n type: string\n description: Field identifier — matches the key in the encrypted object.\n examples: [\"apiSecret\"]\n label:\n type: string\n description: Human-readable label shown in the UI.\n examples: [\"API Secret Key\"]\n required:\n type: boolean\n default: false\n description: When true, the custom field defined by this entry is mandatory — a value for it must be supplied before the connection can be saved.\n position:\n type: number\n description: Display order in the UI form.\n examples: [1]\n helpText:\n type: string\n description: Tooltip text shown next to the field in the UI.\n examples: [\"Your API secret key from the vendor's developer console.\"]\n type:\n type: string\n description: |-\n Optional, legacy field-type hint. The wrapper form ignores it — it always renders these\n custom fields as text inputs (masked) — so it is rarely set.\n _stackId:\n type: string\n format: objectId\n x-celigo-refModel: stacks\n description: Reference to the Celigo Stack whose server-side JavaScript implements this connection.\n x-celigo-ui-override: >-\n Required by the connection form for standalone wrappers (a Stack must be selected), so it is\n enforced as required on create. The API itself accepts a wrapper without it (POST 201), and\n connector-managed wrappers (with _connectorId) omit it — so it is not required on responses.\n examples: [\"566686c4d0b969657e7850ba\"]\n concurrencyLevel:\n type: integer\n description: |\n Maximum number of concurrent operations through this wrapper connection.\n Send no more than the account's licensed maximum (25 standard, 50 with an Environments license).\n minimum: 1\n maximum: 50\n default: 5\n targetConcurrencyLevel:\n type: integer\n description: |\n Target concurrency level for auto-scaling. The system adjusts concurrency\n between 1 and this value based on performance feedback.\n minimum: 1\n maximum: 50\n x-celigo-ai-guidance:\n - |-\n Wrapper connections are custom-built connectors deployed on a Celigo Stack.\n They allow developers to implement custom authentication, data transformation,\n and API interaction logic using server-side JavaScript on a dedicated stack.\n\n ## WHEN TO USE\n Use wrapper connections when:\n - The target API has non-standard authentication not supported by HTTP connections.\n - Custom server-side logic is needed for connection management.\n - You need a fully custom connector deployed on a Celigo Stack.\n\n ## REQUIRED FIELDS\n - pingFunction (name of the function that tests connection health)\n - _stackId (inside this object, as `wrapper._stackId` — references the Celigo Stack)\n\n ## CUSTOM FIELDS\n Use encrypted/unencrypted fields to store connection-specific configuration.\n The wrapper code on the Stack accesses these values at runtime.\n","content_type":"application/yaml; charset=utf-8","language":"yaml","size":6769,"content_sha256":"3fed91327c44197b412840f5d7ae87487a0f82a509f7762b385f8b9e36b5d444"}],"content_json":{"type":"doc","content":[{"type":"paragraph","content":[{"text":"\u003c!-- TIER:1 -->","type":"text"}]},{"type":"heading","attrs":{"level":1},"content":[{"text":"Configuring Connections","type":"text"}]},{"type":"paragraph","content":[{"text":"A connection is a ","type":"text"},{"text":"credential and configuration object","type":"text","marks":[{"type":"strong"}]},{"text":" that lets Celigo communicate with an external system. Every export and import references a connection via ","type":"text"},{"text":"_connectionId","type":"text","marks":[{"type":"code_inline"}]},{"text":". Connections must be created before the resources that use them.","type":"text"}]},{"type":"paragraph","content":[{"text":"Concerns when configuring a connection:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authentication","type":"text","marks":[{"type":"strong"}]},{"text":" -- choosing the right auth method (OAuth, token, basic, key-pair, certificate, etc.) and providing the correct credentials","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Concurrency","type":"text","marks":[{"type":"strong"}]},{"text":" -- how many parallel requests Celigo can make to the target system (","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Can be shared across connections via ","type":"text"},{"text":"_borrowConcurrencyFromConnectionId","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Health monitoring","type":"text","marks":[{"type":"strong"}]},{"text":" -- ping configuration to verify connectivity and detect credential expiration (","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" status)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pre-built connectors","type":"text","marks":[{"type":"strong"}]},{"text":" -- HTTP connectors and trading partner connectors provide pre-configured auth, base URLs, and endpoint definitions for 550+ applications","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Debug logging","type":"text","marks":[{"type":"strong"}]},{"text":" -- temporary debug mode to capture raw request/response data for troubleshooting","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"iClients","type":"text","marks":[{"type":"strong"}]},{"text":" -- reusable credential stores shared across connections: an OAuth app registration (client ID/secret, scopes, token endpoints) or a cloud identity (AWS IAM role, Azure service principal, Google service account). See ","type":"text"},{"text":"iClients section","type":"text","marks":[{"type":"link","attrs":{"href":"#iclients-shared-credential-stores","title":null}}]},{"text":" below.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Used across flows, APIs, and tools.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How to Run the Steps","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill names each step by what it reads or changes; the exact calls depend on how you reach the account. Read the one reference that matches your tools -- both follow the section and step names of this skill:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Celigo MCP tools","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"list_connections","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"upsert_connection","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"get_schema","type":"text","marks":[{"type":"code_inline"}]},{"text":", ...) -- ","type":"text"},{"text":"references/mcp.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/mcp.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The ","type":"text","marks":[{"type":"strong"}]},{"text":"celigo","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" CLI","type":"text","marks":[{"type":"strong"}]},{"text":" -- ","type":"text"},{"text":"references/cli.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/cli.md","title":null}}]}]}]}]},{"type":"paragraph","content":[{"text":"Looking up connections, connectors, templates, and iClients only reads. Creating, updating, deleting, authorizing, registering a connection on an integration, and arming a debug window all write to the account -- do them when the user asked for the change. Diagnosing a connection only reads: when the user asks what's wrong or what to do about it, name the change and leave it to them. A single whitelisted field is a targeted change; anything else is a full-document update that sends every masked credential back exactly as read, which keeps the stored secrets, and never leaves one out -- see ","type":"text"},{"text":"Connection Operations","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-operations","title":null}}]},{"text":". An iClient's update works the same way -- see ","type":"text"},{"text":"iClient Operations","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclients.md#iclient-operations","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Connection Types","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target System","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"type","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Schema","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"REST/GraphQL API (with connector)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/http.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"formType: \"assistant\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", set ","type":"text"},{"text":"_httpConnectorId","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"REST/GraphQL API (manual)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/http.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Three form types: ","type":"text"},{"text":"assistant","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"graph_ql","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite ERP","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"netsuite","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"netsuite.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/netsuite.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" for new connections","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Salesforce CRM","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"salesforce","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"salesforce.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/salesforce.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Omit ","type":"text"},{"text":"salesforce._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" to use Celigo's Connected App","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SQL Server, MySQL, Postgres, Oracle","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Snowflake, BigQuery, Redshift","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check sub-type in schema","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Active Directory, Databricks, DB2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"jdbc","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"jdbc.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/jdbc.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MongoDB/Atlas","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mongodb","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mongodb.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mongodb.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"DynamoDB","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"dynamodb","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"dynamodb.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/dynamodb.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FTP/SFTP/FTPS server","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ftp","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ftp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/ftp.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Optional PGP encryption","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Amazon S3","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s3","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s3.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/s3.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Local filesystem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"filesystem","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"filesystem.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/filesystem.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Requires agent via ","type":"text"},{"text":"_agentId","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AS2 EDI partner","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"as2","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"as2.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/as2.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Celigo VAN (EDI hub)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"van","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"van.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/van.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AI tool server (MCP)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mcp","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mcp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mcp.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stack-deployed connector","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"wrapper","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"wrapper.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/wrapper.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Legacy REST (do not use)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rest","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rest.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rest.yml","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"GraphQL steps get their editor from the connection.","type":"text","marks":[{"type":"strong"}]},{"text":" For a generic GraphQL API, create a ","type":"text"},{"text":"graph_ql","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection whose base URI is the GraphQL endpoint (the connection form can't switch an existing connection to it). For a connector with a GraphQL API, bind the connection to that API with ","type":"text"},{"text":"http._httpConnectorApiId","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- every step on the connection inherits it. GraphQL steps on a connection bound to the app's REST API post to the API root and every record fails (HTTP 406 on Shopify): add a second connection bound to the GraphQL API and re-point those steps to it, rather than replacing the connection on the whole flow. Patching a step's ","type":"text"},{"text":"http.relativeURI","type":"text","marks":[{"type":"code_inline"}]},{"text":" to the GraphQL endpoint isn't a fix: the GraphQL editor writes ","type":"text"},{"text":"/","type":"text","marks":[{"type":"code_inline"}]},{"text":" back on every save, and the step fails again.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Connection Type Decision Matrix","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target system","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Auth method","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Read schema","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Any REST/GraphQL API with a Celigo connector","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Connector-defined (usually OAuth2 or token)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/http.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Any REST/GraphQL API without a connector","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"token","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"basic","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"oauth","type":"text","marks":[{"type":"code_inline"}]},{"text":" (the app on an iClient), ","type":"text"},{"text":"custom","type":"text","marks":[{"type":"code_inline"}]},{"text":" (headers or encrypted fields); also ","type":"text"},{"text":"oauth1","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"jwtbearer","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"cookie","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"digest","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wsse","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"awsiam","type":"text","marks":[{"type":"code_inline"}]},{"text":" (an ","type":"text"},{"text":"awsIam","type":"text","marks":[{"type":"code_inline"}]},{"text":" iClient)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/http.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite ERP","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"netsuite","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Celigo-managed TBA; only the account id)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"netsuite.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/netsuite.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Salesforce CRM","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"salesforce","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OAuth through Celigo's Connected App, or the customer's via an iClient (","type":"text"},{"text":"salesforce._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"salesforce.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/salesforce.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SQL databases (Postgres, MySQL, SQL Server, Oracle)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Username/password + host/port","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Snowflake / BigQuery / Redshift","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Snowflake: key pair or password · BigQuery: service-account key · Redshift: access-key pair or an AWS IAM role (no host or password)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MongoDB / Atlas","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mongodb","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Host list (","type":"text"},{"text":"host:port","type":"text","marks":[{"type":"code_inline"}]},{"text":"), username, password","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mongodb.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mongodb.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"FTP / SFTP / FTPS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ftp","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Username/password or SSH key","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ftp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/ftp.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Amazon S3","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s3","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"IAM access key pair, or an IAM role through an ","type":"text"},{"text":"awsIam","type":"text","marks":[{"type":"code_inline"}]},{"text":" iClient","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s3.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/s3.yml","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"MCP server","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mcp","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"token","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"oauth","type":"text","marks":[{"type":"code_inline"}]},{"text":" (an iClient), or ","type":"text"},{"text":"custom","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mcp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mcp.yml","title":null}}]}]}]}]}]},{"type":"paragraph","content":[{"text":"Which of the two HTTP rows applies is determined by search, not preference: check for a pre-built connector first (search the HTTP connector catalog) and use the manual row only when no connector exists or it doesn't fit -- see ","type":"text"},{"text":"Check for a pre-built connector and global iClient","type":"text","marks":[{"type":"link","attrs":{"href":"#4-check-for-a-pre-built-connector-and-global-iclient","title":null}}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Minimum Required Fields","type":"text"}]},{"type":"paragraph","content":[{"text":"Every connection needs at minimum: ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":", and the type-specific config block. Some of the fields below are required by the connection form rather than the API (each schema says which); send them anyway, or the connection won't connect.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Required fields","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" (connector)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"http\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http.formType: \"assistant\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"assistant_graphql","type":"text","marks":[{"type":"code_inline"}]},{"text":" when the API is GraphQL), ","type":"text"},{"text":"http._httpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http._httpConnectorVersionId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http._httpConnectorApiId","type":"text","marks":[{"type":"code_inline"}]},{"text":" for a connector with more than one API, ","type":"text"},{"text":"http.baseURI","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http.mediaType","type":"text","marks":[{"type":"code_inline"}]},{"text":", and the fields the connector's form asks for -- credentials, and settings such as ","type":"text"},{"text":"settings.storeName","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" (manual)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"http\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http.baseURI","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http.mediaType","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"http.auth.type","type":"text","marks":[{"type":"code_inline"}]},{"text":" and its credentials","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"netsuite","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"netsuite\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"netsuite.authType: \"token-auto\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"netsuite.account","type":"text","marks":[{"type":"code_inline"}]},{"text":" (a non-production account's id carries its suffix, such as ","type":"text"},{"text":"123456_SB1","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"salesforce","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"salesforce\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"salesforce.oauth2FlowType","type":"text","marks":[{"type":"code_inline"}]},{"text":" (plus ","type":"text"},{"text":"salesforce.username","type":"text","marks":[{"type":"code_inline"}]},{"text":" for ","type":"text"},{"text":"jwtBearerToken","type":"text","marks":[{"type":"code_inline"}]},{"text":"), ","type":"text"},{"text":"salesforce.sandbox","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"rdbms\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"rdbms.type","type":"text","marks":[{"type":"code_inline"}]},{"text":", then that database's fields in ","type":"text"},{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]},{"text":" -- BigQuery and Redshift take no host or password","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ftp","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"ftp\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ftp.type","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"ftp","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"sftp","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ftps","type":"text","marks":[{"type":"code_inline"}]},{"text":"), ","type":"text"},{"text":"ftp.hostURI","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ftp.username","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"ftp.password","type":"text","marks":[{"type":"code_inline"}]},{"text":" or (SFTP) ","type":"text"},{"text":"ftp.authKey","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- an unencrypted RSA key in PEM format (OpenSSH-format, passphrase-protected, and PuTTY keys aren't supported); leave ","type":"text"},{"text":"password","type":"text","marks":[{"type":"code_inline"}]},{"text":" out for key-only SFTP","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"s3","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"s3\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"s3.accessKeyId","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"s3.secretAccessKey","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"s3.authType: \"awsIam\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"s3._iClientId","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mongodb","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type: \"mongodb\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mongodb.host","type":"text","marks":[{"type":"code_inline"}]},{"text":" (an array of ","type":"text"},{"text":"host:port","type":"text","marks":[{"type":"code_inline"}]},{"text":"), ","type":"text"},{"text":"mongodb.username","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mongodb.password","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"NetSuite.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" needs only the account: Celigo supplies the OAuth client, so a ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection needs no iClient. REST steps (SuiteTalk records, SuiteQL, custom RESTlets) run on the same ","type":"text"},{"text":"netsuite","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection -- don't build an ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection for them (a REST step on one is refused with 422 ","type":"text"},{"text":"invalid_connection_type","type":"text","marks":[{"type":"code_inline"}]},{"text":"). SuiteTalk and SuiteQL need NetSuite's REST Web Services feature; a NetSuite 403 ","type":"text"},{"text":"FEATURE_DISABLED","type":"text","marks":[{"type":"code_inline"}]},{"text":" means it's off. ","type":"text"},{"text":"netsuite.suiteAppInstalled","type":"text","marks":[{"type":"code_inline"}]},{"text":" reflects only the Celigo SuiteApp as detected at the last authentication and ignores the legacy bundle -- check the SuiteApp and the bundle live before calling either missing.","type":"text"}]},{"type":"paragraph","content":[{"text":"A NetSuite token that stops working.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"INVALID_LOGIN_ATTEMPT","type":"text","marks":[{"type":"code_inline"}]},{"text":" (\"Invalid login attempt.\") on every step and on the test of a token-based connection means NetSuite refused its token: the token was revoked or made inactive (TBA tokens don't expire), the role it's for was taken off its user, made inactive, or lost its token permission (","type":"text"},{"text":"Log in using Access Tokens","type":"text","marks":[{"type":"em"}]},{"text":"), the integration record it was issued for was set to Blocked, or the token belongs to another account (production tokens aren't copied to a sandbox, and a refreshed sandbox needs new ones). Read the connection first and give its account, role and token by name in the answer (","type":"text"},{"text":"netsuite.account","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"environment","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"roleName","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"roleId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"tokenName","type":"text","marks":[{"type":"code_inline"}]},{"text":"): they are what the NetSuite administrator checks. NetSuite's Login Audit Trail (the Detail column) says which cause it is -- ","type":"text"},{"text":"Diagnosing NetSuite Steps","type":"text","marks":[{"type":"link","attrs":{"href":"../configuring-exports/references/netsuite.md#checking-a-refused-token","title":null}}]},{"text":" has where each one is checked. Nothing in Celigo fixes it: a NetSuite administrator restores the role, or creates a new access token for the user and role the connection names (","type":"text"},{"text":"netsuite.roleName","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"roleId","type":"text","marks":[{"type":"code_inline"}]},{"text":"); a person enters the new token on the connection in the Celigo UI (a ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection authorizes again there, signing in with that role); then test the connection and retry the failed records. If someone offers to paste the token into chat, decline -- it goes only into the Celigo UI (","type":"text"},{"text":"Credential Discipline","type":"text","marks":[{"type":"link","attrs":{"href":"#never-accept-or-echo-real-credentials-in-chat","title":null}}]},{"text":").","type":"text"}]},{"type":"paragraph","content":[{"text":"Salesforce.","type":"text","marks":[{"type":"strong"}]},{"text":" A connection authorizes through Celigo's Connected App unless ","type":"text"},{"text":"salesforce._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" names an iClient holding the customer's own; don't send ","type":"text"},{"text":"packagedOAuth","type":"text","marks":[{"type":"code_inline"}]},{"text":", which the platform sets. Choose ","type":"text"},{"text":"oauth2FlowType","type":"text","marks":[{"type":"code_inline"}]},{"text":": ","type":"text"},{"text":"refreshToken","type":"text","marks":[{"type":"code_inline"}]},{"text":" (browser authorization, the default) or ","type":"text"},{"text":"jwtBearerToken","type":"text","marks":[{"type":"code_inline"}]},{"text":" (server-to-server; needs ","type":"text"},{"text":"username","type":"text","marks":[{"type":"code_inline"}]},{"text":" and a Connected App with a digital certificate; a custom app's private key goes on its iClient). ","type":"text"},{"text":"sandbox","type":"text","marks":[{"type":"code_inline"}]},{"text":" must match the org. Never write ","type":"text"},{"text":"salesforce.scope","type":"text","marks":[{"type":"code_inline"}]},{"text":": an empty list is normal, a save from the connection editor resets it, and a custom app's scopes live on its iClient.","type":"text"}]},{"type":"paragraph","content":[{"text":"Celigo's own API","type":"text","marks":[{"type":"strong"}]},{"text":" (lookup caches, jobs, Celigo Storage) is reached from a flow through a connection built from one of Celigo's two connectors. ","type":"text"},{"text":"Celigo APIs","type":"text","marks":[{"type":"em"}]},{"text":" (","type":"text"},{"text":"assistant: \"integratorceligoapi\"","type":"text","marks":[{"type":"code_inline"}]},{"text":") authorizes with client credentials through Celigo's own iClient and needs ","type":"text"},{"text":"accessScope","type":"text","marks":[{"type":"code_inline"}]},{"text":" on create -- ","type":"text"},{"text":"full","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"custom","type":"text","marks":[{"type":"code_inline"}]},{"text":" (listed APIs, listeners, and Celigo Storage folder paths), or ","type":"text"},{"text":"integration","type":"text","marks":[{"type":"code_inline"}]},{"text":" (listed integrations); a create without it is refused with 422 \"Scope is required for this connection\". The connection document never carries the scope -- read it from ","type":"text"},{"text":"GET /v1/accessScope/connections/{_id}","type":"text","marks":[{"type":"code_inline"}]},{"text":"; storage paths are covered in ","type":"text"},{"text":"managing-file-storage","type":"text","marks":[{"type":"link","attrs":{"href":"../managing-file-storage/SKILL.md#8-use-stored-files-in-a-flow","title":null}}]},{"text":". ","type":"text"},{"text":"Celigo integrator.io","type":"text","marks":[{"type":"em"}]},{"text":" (","type":"text"},{"text":"integratorio","type":"text","marks":[{"type":"code_inline"}]},{"text":") takes an API token, which the user enters in the Celigo UI, and ","type":"text"},{"text":"settings.region","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- ","type":"text"},{"text":".","type":"text","marks":[{"type":"code_inline"}]},{"text":" for North America, ","type":"text"},{"text":".eu.","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".au.","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":".ca.","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- which completes its base URI ","type":"text"},{"text":"https://api{{{connection.settings.region}}}integrator.io","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Which Schemas to Read","type":"text"}]},{"type":"paragraph","content":[{"text":"Rule:","type":"text","marks":[{"type":"strong"}]},{"text":" Always read the base ","type":"text"},{"text":"request.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/request.yml","title":null}}]},{"text":" for shared fields, then the type-specific schema for the connection type you are configuring.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Schema Index","type":"text"}]},{"type":"paragraph","content":[{"text":"Connection schemas","type":"text","marks":[{"type":"strong"}]},{"text":" (in ","type":"text"},{"text":"references/schemas/","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/","title":null}}]},{"text":"):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Base fields (all connections):","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"request.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/request.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Response shape:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"response.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/response.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"HTTP:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"http.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/http.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NetSuite:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"netsuite.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/netsuite.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Salesforce:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"salesforce.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/salesforce.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"RDBMS:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"rdbms.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rdbms.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JDBC:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"jdbc.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/jdbc.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MongoDB:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"mongodb.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mongodb.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"DynamoDB:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"dynamodb.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/dynamodb.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FTP:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"ftp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/ftp.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"S3:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"s3.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/s3.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Filesystem:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"filesystem.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/filesystem.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AS2:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"as2.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/as2.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"VAN:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"van.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/van.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MCP:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"mcp.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/mcp.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wrapper:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"wrapper.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/wrapper.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"REST (legacy):","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"rest.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/rest.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OAuth:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"oauth.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/oauth.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JWT:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"jwt.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/jwt.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SSL:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"ssl.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/schemas/ssl.yml","title":null}}]}]}]}]},{"type":"paragraph","content":[{"text":"iClient schemas","type":"text","marks":[{"type":"strong"}]},{"text":" (in ","type":"text"},{"text":"references/iclient-schemas/","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/","title":null}}]},{"text":"):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Base fields:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"request.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/request.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Response shape:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"response.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/response.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OAuth2 providers:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"oauth2.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/oauth2.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NetSuite:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"netsuite.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/netsuite.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Salesforce:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"salesforce.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/salesforce.yml","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"eBay:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"ebay.yml","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclient-schemas/ebay.yml","title":null}}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"configuring-exports","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"Quick Reference","type":"text","marks":[{"type":"link","attrs":{"href":"../configuring-exports/SKILL.md#quick-reference","title":null}}]},{"text":") -- choosing the right export adaptor type and schema for a data source","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"configuring-imports","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"Quick Reference","type":"text","marks":[{"type":"link","attrs":{"href":"../configuring-imports/SKILL.md#quick-reference","title":null}}]},{"text":") -- choosing the right import adaptor type and schema for a data destination","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"building-flows","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"How to Build a Flow","type":"text","marks":[{"type":"link","attrs":{"href":"../building-flows/SKILL.md#how-to-build-a-flow","title":null}}]},{"text":") -- wiring connections, exports, and imports into a flow pipeline","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"\u003c!-- TIER:2 -->","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How to Build a Connection","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Identify the target system","type":"text"}]},{"type":"paragraph","content":[{"text":"What system do you need to connect to? This determines the connection type, auth method, and configuration shape.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Name the connection after the system, not the operation","type":"text"}]},{"type":"paragraph","content":[{"text":"Connection names should describe the ","type":"text"},{"text":"system and environment","type":"text","marks":[{"type":"strong"}]},{"text":" -- not what a specific flow does with them. Connections are shared across exports, imports, and flows, so operation-specific names become misleading as soon as a second resource uses the same connection.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bad (operation-specific)","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Good (system/environment)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Shopify - Customer Upsert","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Shopify - my-store","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft Dynamics 365 Business Central - Companies Export","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft Dynamics 365 Business Central - sandbox","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stripe - Invoice Fetch","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Stripe - Production","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"If the account has multiple environments or instances of the same system, include the distinguishing detail (store name, environment, account ID). Otherwise just the system name is fine.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Check for existing connections","type":"text"}]},{"type":"paragraph","content":[{"text":"Before creating a new connection, check what already exists in the account and marketplace:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Existing connections","type":"text","marks":[{"type":"strong"}]},{"text":" -- search the account by application keyword, and list the connections with their connector identity -- match on that, not on the name (below).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What uses a connection","type":"text","marks":[{"type":"strong"}]},{"text":" -- the exports and imports that reference it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Connection health","type":"text","marks":[{"type":"strong"}]},{"text":" -- offline connections that enabled flows still use, and orphaned connections that nothing uses.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Marketplace templates","type":"text","marks":[{"type":"strong"}]},{"text":" -- search the marketplace for pre-built integration templates, and preview a template's connection model (the connections an install would need).","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Reusing an existing connection avoids duplicate credentials and shares concurrency.","type":"text"}]},{"type":"paragraph","content":[{"text":"Match on identity, not on the name.","type":"text","marks":[{"type":"strong"}]},{"text":" Names are free text: a connection named \"Shopify\" may point somewhere else, and a working one may be called \"Prod store\". For a pre-built HTTP connector the identity is ","type":"text"},{"text":"http._httpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":", plus ","type":"text"},{"text":"http._httpConnectorApiId","type":"text","marks":[{"type":"code_inline"}]},{"text":" when the connector has several API groups (two connections of one connector can target different APIs). ","type":"text"},{"text":"assistant","type":"text","marks":[{"type":"code_inline"}]},{"text":" is the legacy application id -- the connector's ","type":"text"},{"text":"legacyId","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- so a connection that carries only ","type":"text"},{"text":"assistant","type":"text","marks":[{"type":"code_inline"}]},{"text":" belongs to the connector whose ","type":"text"},{"text":"legacyId","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"legacyIds","type":"text","marks":[{"type":"code_inline"}]},{"text":" (in the connector list) holds it, and a legacy ","type":"text"},{"text":"rest","type":"text","marks":[{"type":"code_inline"}]},{"text":" connection is the same family as ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":". For other types it's the ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":" plus its target (the NetSuite account, the database host). Two connections of the same connector and API usually point at different tenants or environments -- read the base URI or account fields before picking one. When more than one fits, prefer the one the flow or Tool you're changing already uses; otherwise confirm with the user.","type":"text"}]},{"type":"paragraph","content":[{"text":"When presenting connection choices to the user","type":"text","marks":[{"type":"strong"}]},{"text":", filter out connections that are ","type":"text"},{"text":"offline: true","type":"text","marks":[{"type":"code_inline"}]},{"text":". Only show online/active connections as options. If ALL matching connections are offline, mention that and let the user decide whether to proceed with an offline connection or fix connectivity first.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Check for a pre-built connector and global iClient","type":"text"}]},{"type":"paragraph","content":[{"text":"For HTTP connections, search for a pre-built connector before configuring manually. Configure by hand only when no connector exists for the application or the connector doesn't support the auth scheme or endpoints you need:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"HTTP connectors","type":"text","marks":[{"type":"strong"}]},{"text":" (550+ apps: Shopify, Stripe, HubSpot, etc.) -- find the connector for the application name or base URL, then read the matching connector in full to see its auth config, endpoints, and resources. Where your surface offers it, scaffold the connection from the connector's own form and preview the body before anything is created.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Trading partner connectors","type":"text","marks":[{"type":"strong"}]},{"text":" (EDI, AS2, VAN) -- search the trading partner catalog. For a partner that has one -- every published connector is AS2 or FTP -- link the connection to it (","type":"text"},{"text":"as2._tpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"ftp._tpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":"; published connectors only) and take the partner's host and AS2 identifiers from the user -- the connector's connection form holds only template stand-ins (","type":"text"},{"text":"building-b2b","type":"text","marks":[{"type":"link","attrs":{"href":"../building-b2b/SKILL.md#3-create-the-connection","title":null}}]},{"text":"). ","type":"text"},{"text":"as2.as2Id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (unique across all integrator.io accounts; generated when omitted) and ","type":"text"},{"text":"as2.partnerId","type":"text","marks":[{"type":"code_inline"}]},{"text":" are fixed at creation -- a later update ignores a new value -- so never invent them. A VAN connection's ","type":"text"},{"text":"as2Id","type":"text","marks":[{"type":"code_inline"}]},{"text":" is unique and fixed the same way (omit it to have the network assign one), and the network assigns ","type":"text"},{"text":"mailboxId","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"If an HTTP connector exists, set ","type":"text"},{"text":"http._httpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"http._httpConnectorVersionId","type":"text","marks":[{"type":"code_inline"}]},{"text":" on the connection, plus ","type":"text"},{"text":"http._httpConnectorApiId","type":"text","marks":[{"type":"code_inline"}]},{"text":" when it has more than one API. The connector provides auth templates, base URL, and pre-built endpoints. The platform resolves the link on save: an id that doesn't resolve is dropped rather than refused, and a top-level ","type":"text"},{"text":"assistant","type":"text","marks":[{"type":"code_inline"}]},{"text":" replaces the connector id you sent -- send ","type":"text"},{"text":"assistant","type":"text","marks":[{"type":"code_inline"}]},{"text":" only as the connector's own ","type":"text"},{"text":"legacyId","type":"text","marks":[{"type":"code_inline"}]},{"text":", and never on an Azure Data Lake Storage Gen2 connection, where it drops the connector ids. Read the connection back to confirm the link. A setting the connector's base URI splices into the host takes the bare identifier: Shopify's base URI is ","type":"text"},{"text":"https://{{{connection.settings.storeName}}}.myshopify.com/...","type":"text","marks":[{"type":"code_inline"}]},{"text":", so ","type":"text"},{"text":"settings.storeName","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":"my-store","type":"text","marks":[{"type":"code_inline"}]},{"text":", not ","type":"text"},{"text":"my-store.myshopify.com","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- a full hostname doubles the domain, and every request goes to a host that doesn't exist.","type":"text"}]},{"type":"paragraph","content":[{"text":"Check for a global iClient.","type":"text","marks":[{"type":"strong"}]},{"text":" Many pre-built connectors ship with a ","type":"text"},{"text":"global (Celigo-managed) iClient","type":"text","marks":[{"type":"strong"}]},{"text":" -- a shared OAuth app registration that handles authorization out of the box (e.g., Microsoft Business Central, Shopify, Google). When a global iClient is available:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use it by default: ","type":"text"},{"text":"http.auth.type: \"oauth\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" with the OAuth fields the connector's connection form pre-configures, including ","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" where the form names the global iClient.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" fall back to static bearer token auth (","type":"text"},{"text":"auth.type: \"token\"","type":"text","marks":[{"type":"code_inline"}]},{"text":") just because you don't have live credentials yet. Create the connection with the correct OAuth auth shape; it stays offline until the user authorizes it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Only create a custom iClient if the customer has their own app registration (e.g., their own Azure AD app, Shopify private app) or if the global iClient doesn't have the required scopes/consent for their tenant. Point the connection at it with ","type":"text"},{"text":"http.auth.oauth.useIClientFields: true","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":". The app can't live on the connection itself: an HTTP connection doesn't store an OAuth client id or secret sent on it (the save answers 201 without them), and its authorization then fails with ","type":"text"},{"text":"unknown http authURI","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Find the global iClient in the connector's connection form (its full definition), not on another connection. A connector OAuth connection either leaves ","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" empty -- the global iClient is applied when the user authorizes -- or names Celigo's published iClient. That iClient lives in Celigo's account, so reading it from the customer's account returns 404 ","type":"text"},{"text":"invalid_ref","type":"text","marks":[{"type":"code_inline"}]},{"text":", and nothing on it can be changed. That's normal, not a deleted iClient; an Integration App's connections can point at their publisher's iClient the same way.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"5. Choose the type, auth method, and build","type":"text"}]},{"type":"paragraph","content":[{"text":"Use the ","type":"text"},{"text":"Connection Types","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-types","title":null}}]},{"text":" table above to pick the ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":" value and open the matching schema for available auth options and required fields.","type":"text"}]},{"type":"paragraph","content":[{"text":"Every connection needs at minimum: ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":", and the type-specific config block (","type":"text"},{"text":"http{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"netsuite{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ftp{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.).","type":"text"}]},{"type":"paragraph","content":[{"text":"Placeholder connections must use the correct auth shape.","type":"text","marks":[{"type":"strong"}]},{"text":" When creating a connection without live credentials (e.g., demo, placeholder, or pre-staging), always configure the full auth structure the connection will ultimately use -- OAuth type, iClient reference, grant type, etc. This ensures the connection can be authorized in place later without reconfiguration. Never substitute static token auth as a shortcut for an OAuth connection. Don't send ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" either: it's read-only, and only the platform's connection test sets it. A save runs that test when the connection has one -- for HTTP, only when a ping is configured -- and the result arrives in the save's response or, when the target is slow to answer, seconds later as a ","type":"text"},{"text":"system","type":"text","marks":[{"type":"code_inline"}]},{"text":" change in the audit log. A placeholder that has a test reads offline until the user enters the credentials or authorizes it; one without a test carries no ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" flag at all.","type":"text"}]},{"type":"paragraph","content":[{"text":"An OAuth connection on an existing iClient","type":"text","marks":[{"type":"strong"}]},{"text":" takes the auth shape and the reference; the iClient supplies the client, the endpoints, and the grant type:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"name\": \"Acme ERP - Production\",\n \"type\": \"http\",\n \"http\": {\n \"formType\": \"http\",\n \"baseURI\": \"https://erp.example.com/api/v3\",\n \"mediaType\": \"json\",\n \"_iClientId\": \"\u003ciClientId>\",\n \"auth\": { \"type\": \"oauth\", \"oauth\": { \"useIClientFields\": true } }\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"_iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" sits on the ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" block, beside ","type":"text"},{"text":"auth","type":"text","marks":[{"type":"code_inline"}]},{"text":", not inside it. An authorization-code connection holds no tokens until a person authorizes it in a browser -- in the Celigo UI, or through your surface's authorize step (step 6) -- so finish by telling the user to do that.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"6. Test the connection","type":"text"}]},{"type":"paragraph","content":[{"text":"Ping the connection to confirm it reaches the target system with its credentials. A ping answers HTTP 200 whether the test passed or failed, so read the body: ","type":"text"},{"text":"{code: 200}","type":"text","marks":[{"type":"code_inline"}]},{"text":" is a pass and ","type":"text"},{"text":"{errors: [...]}","type":"text","marks":[{"type":"code_inline"}]},{"text":" a failure -- ","type":"text"},{"text":"invalid_host","type":"text","marks":[{"type":"code_inline"}]},{"text":" (DNS), ","type":"text"},{"text":"missing_token","type":"text","marks":[{"type":"code_inline"}]},{"text":" (re-authorize), or a ","type":"text"},{"text":"401","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"source: application","type":"text","marks":[{"type":"code_inline"}]},{"text":" (the remote system refused the credential). Each adaptor runs its own check: HTTP calls its configured ping endpoint -- with none configured, the test passes without sending any request -- databases open a driver session, MCP lists the server's tools (","type":"text"},{"text":"mcp_tools_list_failed","type":"text","marks":[{"type":"code_inline"}]},{"text":" when that list doesn't come back), NetSuite and Salesforce validate the token. A pass proves only what that check exercised; with no ping configured, or a ping endpoint that needs no auth, the first real request is the real test, so give an HTTP connection a ping on an endpoint that needs its credentials. An OAuth connection requests a token only after the target answers 401, so a ping that needs no auth passes without ever fetching one.","type":"text"}]},{"type":"paragraph","content":[{"text":"Authorization-code OAuth connections (and Salesforce's ","type":"text"},{"text":"refreshToken","type":"text","marks":[{"type":"code_inline"}]},{"text":" flow) need a browser authorization first -- the tokens come from the provider's redirect, so a person completes it. The provider's app must list the redirect URI the authorization URL carries (","type":"text"},{"text":"redirect_uri","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"https://integrator.io/connection/oauth2callback","type":"text","marks":[{"type":"code_inline"}]},{"text":" on a North America account). The callback sets ","type":"text"},{"text":"needsAuthorization: false","type":"text","marks":[{"type":"code_inline"}]},{"text":"; a connection never authorized has no such key, so its absence proves nothing. Each new authorization URL replaces the one before it: with PKCE (an iClient's ","type":"text"},{"text":"oauth2.pkceCodeChallengeMethod","type":"text","marks":[{"type":"code_inline"}]},{"text":", and every Salesforce connection) only the most recent URL can finish, so authorize once, in one window. An MCP connection authorizes the same way, through an iClient: Celigo doesn't discover a server's OAuth endpoints or register a client dynamically, so register an app with the vendor that lists the callback above, put its client and URLs on a ","type":"text"},{"text":"custom_oauth2","type":"text","marks":[{"type":"code_inline"}]},{"text":" iClient, and expect the authorization to end with a tool listing that fails it when the server refuses the call. Client-credentials and password grants, Salesforce JWT bearer, and cloud-identity iClients need no browser step: the platform requests the token itself, and as with any connection, a test whose ping needs no auth doesn't prove those credentials. Not every surface can ping or authorize; your reference names the fallback.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Connection Operations","type":"text"}]},{"type":"paragraph","content":[{"text":"Beyond building one, the operations on a connection are:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CRUD","type":"text","marks":[{"type":"strong"}]},{"text":" -- list, read, create, update (a full-document replace), and delete","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test connectivity","type":"text","marks":[{"type":"strong"}]},{"text":" -- ping","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"OAuth authorization","type":"text","marks":[{"type":"strong"}]},{"text":" -- the browser flow that obtains the tokens","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Debug","type":"text","marks":[{"type":"strong"}]},{"text":" -- arm and disarm a debug window, and read the debug logs it captured","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Integration-level connection management","type":"text","marks":[{"type":"strong"}]},{"text":" -- register connections on an integration, or deregister them","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Replace a connection","type":"text","marks":[{"type":"strong"}]},{"text":" -- repoint steps to another connection in one call: every step of a flow, API, or Tool, or one export or import","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Targeted changes vs full updates.","type":"text","marks":[{"type":"strong"}]},{"text":" Only PATCH-whitelisted fields can be changed on their own: ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":", the debug window (","type":"text"},{"text":"debugDate","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"debugUntil","type":"text","marks":[{"type":"code_inline"}]},{"text":"), the credential-free concurrency settings (","type":"text"},{"text":"\u003cadaptor>.concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\u003cadaptor>.targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"_borrowConcurrencyFromConnectionId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"autoRecoverRateLimitErrors","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- ","type":"text"},{"text":"\u003cadaptor>","type":"text","marks":[{"type":"code_inline"}]},{"text":" is the connection's ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":" block, such as ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":"; a path under another block is accepted and never read), and ","type":"text"},{"text":"endUserProvidedFields","type":"text","marks":[{"type":"code_inline"}]},{"text":". A PATCH never reads or re-sends the masked credentials GET returns as ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":", so it's safe. Every other field takes a full-document update: send each secret back as the masked ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" the GET returned, which keeps the stored secret, or as a new value. An omitted secret or a placeholder clears the stored credential -- see ","type":"text"},{"text":"Credential Discipline","type":"text","marks":[{"type":"link","attrs":{"href":"#never-accept-or-echo-real-credentials-in-chat","title":null}}]},{"text":". So a PATCH refused for a header, the base URI or an auth setting means \"send the full update\", not \"edit it in the UI\": a change that keeps the stored secrets needs nothing from the user. iClients follow the same mask rule, with two provider exceptions -- see ","type":"text"},{"text":"iClient Operations","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclients.md#iclient-operations","title":null}}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"endUserProvidedFields","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" belongs only on a connection an MCP server collects end-user credentials for: list the credential and tenant fields each end user supplies on their own copy (","type":"text"},{"text":"http.encrypted.apiKey","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"rdbms.user","type":"text","marks":[{"type":"code_inline"}]},{"text":"). A path the account owns -- ","type":"text"},{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"_agentId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wrapper._stackId","type":"text","marks":[{"type":"code_inline"}]},{"text":", any ","type":"text"},{"text":"\u003cadaptor>._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- is refused with 422 ","type":"text"},{"text":"mcp_end_user_provided_field_not_allowed","type":"text","marks":[{"type":"code_inline"}]},{"text":". A full update that leaves the field out keeps it (send ","type":"text"},{"text":"null","type":"text","marks":[{"type":"code_inline"}]},{"text":" to clear it), and any change to the list makes every end user set up again.","type":"text"}]},{"type":"paragraph","content":[{"text":"Replacing a connection.","type":"text","marks":[{"type":"strong"}]},{"text":" The replacement must be the same adaptor type (422 otherwise), and for HTTP it should reach the same application: each step keeps its relative URI, which was written for the old connection's API, so a swap between HTTP connections on different connectors breaks every step on its first run -- change each step's connection and endpoint together instead. Replacing a connection on a flow, or on one export or import, cancels the runs in flight. A replace changes only the steps of the flow, API, Tool, export, or import it runs on; check separately anything else that used the old connection, such as a Tool's per-consumer bindings, an AI agent's MCP connection, or a sync.","type":"text"}]},{"type":"paragraph","content":[{"text":"Update in place or create a new one.","type":"text","marks":[{"type":"strong"}]},{"text":" Rotate a credential in place: every step keeps working through the same connection. When the identity changes -- another account, store, user, or app -- create a new connection and replace it on the steps, so nothing silently starts reading or writing a different system.","type":"text"}]},{"type":"paragraph","content":[{"text":"Deregistering","type":"text","marks":[{"type":"strong"}]},{"text":" a connection from an integration is refused (400 ","type":"text"},{"text":"not_allowed","type":"text","marks":[{"type":"code_inline"}]},{"text":") while a step in the integration's flows, APIs, or Tools uses it, or an alias on the integration or one of its flows points at it. Replace the connection on those steps and retarget the aliases first; steps already in the recycle bin don't count. Deregistering never changes the connection itself.","type":"text"}]},{"type":"paragraph","content":[{"text":"Deleting.","type":"text","marks":[{"type":"strong"}]},{"text":" A connection delete is refused with 422 while anything still uses it, and the message names each blocker: every export or import on it, the flows they're steps of, and any connection that borrows its concurrency (clearing the borrow is enough). Registration on an integration doesn't block a delete, and neither do steps already in the recycle bin. A deleted connection stays in the recycle bin for 30 days and can be restored; purging it sooner needs the binned flows and steps that pointed at it purged first (422 ","type":"text"},{"text":"referenced by Export","type":"text","marks":[{"type":"code_inline"}]},{"text":" otherwise).","type":"text"}]},{"type":"paragraph","content":[{"text":"Integration App connections.","type":"text","marks":[{"type":"strong"}]},{"text":" A connection with ","type":"text"},{"text":"_connectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":" belongs to an Integration App, which may lock some of its fields: a full update answers 200 but keeps the app's value for a locked field, and a targeted change of one is refused with 422. Read the connection back and report what didn't persist rather than retrying.","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c!-- TIER:3 -->","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pre-Submit Checklist","type":"text"}]},{"type":"paragraph","content":[{"text":"Before creating or updating a connection, verify:","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":" describes the system/environment, not a specific operation (e.g., \"Shopify - my-store\", not \"Shopify - Customer Upsert\")","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":" matches the target system (see ","type":"text"},{"text":"Connection Types","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-types","title":null}}]},{"text":")","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Type-specific config block is present (","type":"text"},{"text":"http{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"netsuite{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"rdbms{}","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"On a create, auth credentials are real values (or placeholders on a connection nothing uses yet), never a ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" copied from another connection; on an update, each secret is this connection's own mask, exactly as read, or a new value -- never left out","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"No credential the user pasted into chat is anywhere in the body -- a placeholder holds its place until the user enters the rotated one in the UI","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For HTTP: a pre-built connector search was done (the HTTP connector catalog); manual config only because none exists or it doesn't fit","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For HTTP connectors: ","type":"text"},{"text":"http._httpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"http._httpConnectorVersionId","type":"text","marks":[{"type":"code_inline"}]},{"text":" are set","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Reusing an existing connection: it was matched on connector identity (","type":"text"},{"text":"http._httpConnectorId","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"http._httpConnectorApiId","type":"text","marks":[{"type":"code_inline"}]},{"text":", or the type and target), not its name","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For OAuth connections: uses global iClient if connector provides one; custom iClient only when needed","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For OAuth connections: ","type":"text"},{"text":"auth.type","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":"\"oauth\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" (not ","type":"text"},{"text":"\"token\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" with a static bearer), even on a placeholder nobody has authorized yet","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For OAuth through an existing iClient: ","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" on the ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":" block, ","type":"text"},{"text":"http.auth.oauth.useIClientFields: true","type":"text","marks":[{"type":"code_inline"}]},{"text":", and the user told to authorize the connection","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For a customer's own OAuth app: the client id and secret are on a ","type":"text"},{"text":"custom_oauth2","type":"text","marks":[{"type":"code_inline"}]},{"text":" iClient whose ","type":"text"},{"text":"validDomainNames","type":"text","marks":[{"type":"code_inline"}]},{"text":" lists the OAuth URLs' registrable domains -- an HTTP connection doesn't keep them","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For a Celigo APIs connection: ","type":"text"},{"text":"accessScope","type":"text","marks":[{"type":"code_inline"}]},{"text":" is in the create body","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" in the body -- it's read-only","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For NetSuite: ","type":"text"},{"text":"netsuite.authType","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" (not deprecated ","type":"text"},{"text":"basic","type":"text","marks":[{"type":"code_inline"}]},{"text":"), with ","type":"text"},{"text":"netsuite.account","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For Salesforce: ","type":"text"},{"text":"oauth2FlowType","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"sandbox","type":"text","marks":[{"type":"code_inline"}]},{"text":" set; no ","type":"text"},{"text":"packagedOAuth","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"For RDBMS: ","type":"text"},{"text":"rdbms.type","type":"text","marks":[{"type":"code_inline"}]},{"text":" plus that database's required fields (BigQuery and Redshift take no host or password)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Gotchas","type":"text"}]},{"type":"paragraph","content":[{"text":"These are connection gotchas. iClients follow the same mask rule, with two provider exceptions -- see ","type":"text"},{"text":"iClient Gotchas","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclients.md#iclient-gotchas","title":null}}]},{"text":".","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GET masks credentials, and the mask keeps them.","type":"text","marks":[{"type":"strong"}]},{"text":" Passwords, tokens, and secrets are returned as ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":". Sent back unchanged in a full update, the mask keeps the stored secret: the platform treats the mask on an encrypted field that already holds a secret as \"unchanged\". Leaving the field out clears it; on a static-token connection (no ","type":"text"},{"text":"refreshMethod","type":"text","marks":[{"type":"code_inline"}]},{"text":"), an update without the token is refused with 422 instead. A full update that still contains ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" is refused unless it is explicitly forced or confirmed (your reference says how on each surface) -- for masks read from this connection, that is safe. Some tool descriptions and refusals still say to leave a secret out to keep it; that is out of date -- leaving it out is what clears it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PUT erases omitted fields.","type":"text","marks":[{"type":"strong"}]},{"text":" Always GET first, modify, then PUT the complete object, with every secret either the mask you read or a new value. Leave out only the read-only fields the GET adds (","type":"text"},{"text":"_id","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"createdAt","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"lastModified","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"queues","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"sandbox","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"connectionRole","type":"text","marks":[{"type":"code_inline"}]},{"text":"). For a rename, debug window, or concurrency change, make a targeted change instead -- no credentials involved.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authorization-code OAuth connections need browser authorization after creation.","type":"text","marks":[{"type":"strong"}]},{"text":" Creating via API sets up the shell, but tokens come from a browser redirect, so a person has to complete the authorization. Say so when you report the new connection: it doesn't work until the user authorizes it in the Celigo UI. The scopes are requested at that moment (the authorization URL carries them): after adding a scope, authorize again, and never put a placeholder in a scope field. Client-credentials, password, Salesforce JWT bearer, and cloud-identity connections get their tokens without a browser.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"rest","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" type is legacy.","type":"text","marks":[{"type":"strong"}]},{"text":" Always use ","type":"text"},{"text":"type: \"http\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" for new REST connections.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NetSuite ","type":"text","marks":[{"type":"strong"}]},{"text":"basic","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" auth is deprecated.","type":"text","marks":[{"type":"strong"}]},{"text":" Use ","type":"text"},{"text":"token-auto","type":"text","marks":[{"type":"code_inline"}]},{"text":" (Celigo-managed TBA) for new connections.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Debug logs are connection-scoped.","type":"text","marks":[{"type":"strong"}]},{"text":" Enabling debug captures request/response data for all flows using that connection.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"_borrowConcurrencyFromConnectionId","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" shares slots.","type":"text","marks":[{"type":"strong"}]},{"text":" The borrowing connection's ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ignored, its work shares the parent's queue, and borrowing is one level -- see ","type":"text"},{"text":"Borrowing concurrency","type":"text","marks":[{"type":"link","attrs":{"href":"#borrowing-concurrency","title":null}}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Name connections after the system, not the operation.","type":"text","marks":[{"type":"strong"}]},{"text":" Connections are shared across resources. \"Shopify - my-store\" is correct; \"Shopify - Customer Upsert\" is not.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use the global iClient for OAuth connectors.","type":"text","marks":[{"type":"strong"}]},{"text":" When a pre-built connector ships with a global iClient, use it with ","type":"text"},{"text":"auth.type: \"oauth\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- do not substitute ","type":"text"},{"text":"auth.type: \"token\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" with a static bearer token, even for offline/dummy connections. Static tokens expire and produce the wrong auth shape.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"An OAuth connection's ","type":"text","marks":[{"type":"strong"}]},{"text":"authURI","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" and ","type":"text","marks":[{"type":"strong"}]},{"text":"tokenURI","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" are fixed.","type":"text","marks":[{"type":"strong"}]},{"text":" An update that changes either is refused with 422 (\"Updating the value in tokenURI is not allowed for oauth connections due to security reasons\"). For new OAuth URLs, create a new connection and replace it on the steps.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A create's ","type":"text","marks":[{"type":"strong"}]},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" doesn't stick while auto-recover is on.","type":"text","marks":[{"type":"strong"}]},{"text":" A create gets auto-recover unless the body sends ","type":"text"},{"text":"autoRecoverRateLimitErrors: false","type":"text","marks":[{"type":"code_inline"}]},{"text":", and with it on the save stores ","type":"text"},{"text":"\u003ctype>.targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" as both the target and the level -- or the adaptor default when no target is sent (HTTP 25, FTP 1, most other adaptors 5) -- whatever ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" the body carried. An HTTP create that asks for 10 can run at 25. Put the level in ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":", or send ","type":"text"},{"text":"autoRecoverRateLimitErrors: false","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" (see ","type":"text"},{"text":"Auto-recover rate-limit errors","type":"text","marks":[{"type":"link","attrs":{"href":"#auto-recover-rate-limit-errors","title":null}}]},{"text":").","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Errors","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cause","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"401 Unauthorized","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Invalid or expired credentials","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verify auth credentials; for OAuth, re-authorize the connection in a browser","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"403 Forbidden","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Valid credentials but insufficient permissions","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check the user/role permissions in the target system","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"422 Unprocessable Entity","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- invalid type","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"type","type":"text","marks":[{"type":"code_inline"}]},{"text":" value is not recognized or misspelled","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use exact values from ","type":"text"},{"text":"Connection Types","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-types","title":null}}]},{"text":": ","type":"text"},{"text":"http","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"netsuite","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"salesforce","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"rdbms","type":"text","marks":[{"type":"code_inline"}]},{"text":", etc.","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"422 Unprocessable Entity","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- missing fields","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Required type-specific fields are absent","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check ","type":"text"},{"text":"Minimum Required Fields","type":"text","marks":[{"type":"link","attrs":{"href":"#minimum-required-fields","title":null}}]},{"text":" for the connection type","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Delete: 422 ","type":"text"},{"text":"\u003ctype> \u003cid> must be deleted before you can delete connection \u003cid>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"An export or import still uses the connection (the flow it's a step of is named too), or another connection borrows its concurrency","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replace the connection on those steps or delete them, and clear the borrower's ","type":"text"},{"text":"_borrowConcurrencyFromConnectionId","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- see Deleting under ","type":"text"},{"text":"Connection Operations","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-operations","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Deregister: 400 ","type":"text"},{"text":"The connection is being actively used by the integration","type":"text","marks":[{"type":"code_inline"}]},{"text":" (or ","type":"text"},{"text":"referenced by an alias","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A step in the integration's flows, APIs, or Tools uses it, or an alias points at it","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replace the connection on those steps, and retarget or remove the alias","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Borrowing: 422 ","type":"text"},{"text":"already borrowing concurrency from another connection","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"there are already connections borowing from it","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"cannot borrow concurrency from itself","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Borrowing is one level, and never from itself","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Point every borrower at the one parent that borrows from nothing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"iClient delete: 422 ","type":"text"},{"text":"this document is referenced by Connection : \u003cid>","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A connection still points at the iClient -- possibly a deleted one in the recycle bin, which the dependency list doesn't show","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Re-point that connection, or purge it from the recycle bin, then delete the iClient","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A ping answers HTTP 200 with ","type":"text"},{"text":"errors","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The test failed: ","type":"text"},{"text":"invalid_host","type":"text","marks":[{"type":"code_inline"}]},{"text":" (DNS), ","type":"text"},{"text":"missing_token","type":"text","marks":[{"type":"code_inline"}]},{"text":" (not authorized), or ","type":"text"},{"text":"401","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"source: application","type":"text","marks":[{"type":"code_inline"}]},{"text":" (the remote system refused the credential)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix the host or URL, re-authorize, or have the user re-enter the credential in the UI; for on-prem systems, check the agent","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ECONNREFUSED","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"ETIMEDOUT","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Network-level failure to target system","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check host/port and DNS resolution; if the target allows only approved IP addresses, it must allow Celigo's outbound ranges (","type":"text"},{"text":"Partner IP allow lists","type":"text","marks":[{"type":"link","attrs":{"href":"#partner-ip-allow-lists","title":null}}]},{"text":") -- a network policy won't help; for on-prem systems, verify ","type":"text"},{"text":"_agentId","type":"text","marks":[{"type":"code_inline"}]},{"text":" is set","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"OAuth ","type":"text"},{"text":"invalid_grant","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Refresh token expired or revoked","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Re-authorize the connection in a browser","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Authorizing: the provider answers ","type":"text"},{"text":"invalid_grant","type":"text","marks":[{"type":"code_inline"}]},{"text":" ... ","type":"text"},{"text":"invalid code verifier","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A newer authorization URL was issued for this connection (another tab, a second try): with PKCE it replaced the stored code verifier","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Close the other authorization windows and authorize again from one new URL","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"token_extraction_failed","type":"text","marks":[{"type":"code_inline"}]},{"text":" \"Failed to extract token value from refresh token response\", with HTML in ","type":"text"},{"text":"ResponseBody","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The token refresh got a web page, not JSON: the iClient's token or refresh URL points at a login or authorization page","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Point the iClient's ","type":"text"},{"text":"token.uri","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"refresh.uri","type":"text","marks":[{"type":"code_inline"}]},{"text":" at the provider's token endpoint","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The user pastes a provider sign-in URL carrying ","type":"text"},{"text":"state","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"redirect_uri=.../connection/oauth2callback","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"That's the start of an authorization, not its result","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ask what the provider's page showed after they signed in","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Authorizing: 422 ","type":"text"},{"text":"Expected field: authURI in the Connection to be present.","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Not an authorization-code connection -- nothing to authorize in a browser","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Client credentials, password, JWT bearer, and cloud identities get tokens on their own; test the connection instead","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Authorizing: 422 ","type":"text"},{"text":"unknown http authURI: \"\u003cdomain>\"","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The connection has no iClient to authorize with -- an HTTP connection keeps no client id or secret of its own","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a ","type":"text"},{"text":"custom_oauth2","type":"text","marks":[{"type":"code_inline"}]},{"text":" iClient with the app and ","type":"text"},{"text":"validDomainNames","type":"text","marks":[{"type":"code_inline"}]},{"text":", and point the connection at it (","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"useIClientFields: true","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"authURI","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"tokenURI","type":"text","marks":[{"type":"code_inline"}]},{"text":" unchanged)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Authorizing or testing: ","type":"text"},{"text":"The domain of request url should be present in iClient.oauth2.validDomainNames","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The iClient's ","type":"text"},{"text":"validDomainNames","type":"text","marks":[{"type":"code_inline"}]},{"text":" lacks the registrable domain of the authorization, token, or revoke URL","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add that registrable domain (","type":"text"},{"text":"example.com","type":"text","marks":[{"type":"code_inline"}]},{"text":", not ","type":"text"},{"text":"auth.example.com","type":"text","marks":[{"type":"code_inline"}]},{"text":") to the iClient","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"422 ","type":"text"},{"text":"Updating the value in tokenURI is not allowed for oauth connections","type":"text","marks":[{"type":"code_inline"}]},{"text":" (or ","type":"text"},{"text":"authURI","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"An update changed an OAuth connection's token or authorization URL","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Those URLs are fixed: create a new connection and replace it on the steps","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"422 ","type":"text"},{"text":"Scope is required for this connection","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A Celigo APIs connection created without ","type":"text"},{"text":"accessScope","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add ","type":"text"},{"text":"accessScope","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- see Celigo's own API under ","type":"text"},{"text":"Minimum Required Fields","type":"text","marks":[{"type":"link","attrs":{"href":"#minimum-required-fields","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"422 ","type":"text"},{"text":"fileserver_loopback_not_supported","type":"text","marks":[{"type":"code_inline"}]},{"text":" \"This connection points at this environment's own Celigo file server ...\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"An FTP connection's host and ","type":"text"},{"text":"@\u003cidentifier>","type":"text","marks":[{"type":"code_inline"}]},{"text":" username are this environment's own Celigo file server","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Don't connect to it: read the files from Celigo Storage in the flow (","type":"text"},{"text":"managing-file-storage > 8. Use stored files in a flow","type":"text","marks":[{"type":"link","attrs":{"href":"../managing-file-storage/SKILL.md#8-use-stored-files-in-a-flow","title":null}}]},{"text":"). Another environment's server on the same host, such as a trading partner's, is fine","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite 403 ","type":"text"},{"text":"FEATURE_DISABLED","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite's REST Web Services feature is off (SuiteTalk and SuiteQL steps)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A NetSuite administrator enables it; custom RESTlets don't need it","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite ","type":"text"},{"text":"INVALID_LOGIN_ATTEMPT","type":"text","marks":[{"type":"code_inline"}]},{"text":" (\"Invalid login attempt.\") on every step and the test","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NetSuite refused the connection's token: revoked or inactive, or its role changed","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A new token for the role the connection names, entered in the Celigo UI, then a connection test -- see NetSuite under ","type":"text"},{"text":"Minimum Required Fields","type":"text","marks":[{"type":"link","attrs":{"href":"#minimum-required-fields","title":null}}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ping: ","type":"text"},{"text":"mcp_tools_list_failed","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The MCP server didn't return its tool list","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check ","type":"text"},{"text":"mcp.serverURL","type":"text","marks":[{"type":"code_inline"}]},{"text":" and the token or OAuth iClient; authorize an OAuth server again","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" saved as a connection credential (authentication fails after a save)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A mask was sent where no secret was stored: a create built from another connection's document, or a mask placed on a field that was empty","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"A mask keeps only a secret the field already holds; the real value has to go in that field, so the user enters it in the Celigo UI","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"429 Too Many Requests","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Destination rate limit exceeded. An HTTP step has already retried the request three times before reporting it, each after the wait the response's ","type":"text"},{"text":"Retry-After","type":"text","marks":[{"type":"code_inline"}]},{"text":" header gives (or the header ","type":"text"},{"text":"http.retryHeader","type":"text","marks":[{"type":"code_inline"}]},{"text":" names; usually half a second when there's none) -- on an Amazon SP-API connection (","type":"text"},{"text":"http.type","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Amazon-SP-API","type":"text","marks":[{"type":"code_inline"}]},{"text":"), the wait Amazon's ","type":"text"},{"text":"x-amzn-RateLimit-Limit","type":"text","marks":[{"type":"code_inline"}]},{"text":" header implies -- so the limit stayed spent across those tries","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"If auto-recover is enabled, the connection throttles and retries automatically; to cap it lower, reduce ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" is platform-managed while auto-recover is on). Otherwise enable auto-recover, with ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" in the same change, or lower ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":". Both are credential-free targeted changes. If another connection reaches the same external account, they share its limit -- see ","type":"text"},{"text":"Connections as concurrency queues","type":"text","marks":[{"type":"link","attrs":{"href":"#connections-as-concurrency-queues----throughput-and-governance","title":null}}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Credential Discipline & Runtime Behavior","type":"text"}]},{"type":"paragraph","content":[{"text":"How connections behave once they exist -- the credential rules every update must follow, and the runtime model (state, queues, rate-limit recovery, debug) to reason about when troubleshooting.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Never accept or echo real credentials in chat","type":"text"}]},{"type":"paragraph","content":[{"text":"A full connection update (PUT) carries every credential field, and each one goes back either as the masked ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" the GET returned, which keeps the stored secret, or as a new value. A new value is a real credential, and chat conversations are logged in clear text, so ","type":"text"},{"text":"never accept, request, or echo a real credential","type":"text","marks":[{"type":"strong"}]},{"text":" (API key, OAuth token or client secret, SFTP password, cert key, AS2 cert pair) in chat.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Settings that never need credentials go through PATCH.","type":"text","marks":[{"type":"strong"}]},{"text":" Rename, the debug window, the concurrency settings, borrowing, auto-recover, and ","type":"text"},{"text":"endUserProvidedFields","type":"text","marks":[{"type":"code_inline"}]},{"text":" are targeted single-field changes (the whitelist is under ","type":"text"},{"text":"Connection Operations","type":"text","marks":[{"type":"link","attrs":{"href":"#connection-operations","title":null}}]},{"text":"). PATCH never reads or changes the stored credentials, so these need no credential follow-up -- don't tell the user to re-enter anything after a rename or a concurrency change.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Everything else is a full update: send the secrets back as their masks.","type":"text","marks":[{"type":"strong"}]},{"text":" Read the connection, change what you need, and send the complete document with every ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" left exactly as read -- each mask keeps its stored secret. Never drop a secret field to keep it, even where a tool's description says to: an omitted secret or a placeholder clears the stored credential and leaves the connection -- and every flow on it -- offline until someone re-enters it (a static-token connection, one with no ","type":"text"},{"text":"refreshMethod","type":"text","marks":[{"type":"code_inline"}]},{"text":", sent without its token is refused with 422 instead). That makes a base URI, endpoint, or header change safe as a full update. A credential or auth-type change needs the new secret, so describe it and have the user make it in the Celigo UI, where re-entering the credential (or re-authorizing, for OAuth) is part of the save. Placeholder credentials belong only on a connection nothing depends on yet, and the user must enter the real values in the UI before it works.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If a user pastes a real credential, treat it as compromised, full stop. Never write it anywhere -- not into the secret field, a header, or any other field -- and never repeat it back. The only correct mitigation: (1) rotate the credential at the external system itself -- regenerate the API key, reset the OAuth grant, rotate the SFTP password, revoke and reissue the cert pair -- then (2) update the connection in the Celigo UI with the rotated value. This holds no matter how trivial the credential looks (a sandbox key, a stale password, a client secret the user thinks is unused).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A pasted credential doesn't stop the build.","type":"text","marks":[{"type":"strong"}]},{"text":" Create the rest of the connection with the auth shape it needs and a placeholder such as ","type":"text"},{"text":"REPLACE_IN_CELIGO_UI","type":"text","marks":[{"type":"code_inline"}]},{"text":" in the secret field -- for token auth the field can't simply be left empty: a create without a token is refused with 422 ","type":"text"},{"text":"Expected field: refreshMethod to be present.","type":"text","marks":[{"type":"code_inline"}]},{"text":" Then tell the user three things: the pasted credential wasn't stored; it is compromised because it was shared in chat, so they rotate it at the external system; and they enter the rotated one on the connection in the Celigo UI, which is when the connection starts working.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"The credentials live on the durable connection record; the runtime auth state (token still valid, cert still trusted, system reachable) is separate and ephemeral.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Online / offline -- fix the shared connection, not each flow","type":"text"}]},{"type":"paragraph","content":[{"text":"A connection is ","type":"text"},{"text":"online","type":"text","marks":[{"type":"strong"}]},{"text":" (credentials valid, target reachable, every dependent can run) or ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"strong"}]},{"text":" (token expired, API changed, network unreachable, credentials rotated without updating Celigo, cert expired). The connection resource exists in either state -- going offline doesn't delete it. Probe it with a ping, or read the connection's ","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" flag.","type":"text"}]},{"type":"paragraph","content":[{"text":"When a user reports \"my flow is failing\" and the root cause is the connection, ","type":"text"},{"text":"fix the shared connection, not each dependent flow.","type":"text","marks":[{"type":"strong"}]},{"text":" One connection backs many consumers (flows, APIs, Tools, AI agents); every dependent recovers the moment the connection is back online. That one-fix-all-recover payoff is the whole point of the connection abstraction.","type":"text"}]},{"type":"paragraph","content":[{"text":"Find out why it went offline before changing anything.","type":"text","marks":[{"type":"strong"}]},{"text":" The connection's audit log shows when it flipped (","type":"text"},{"text":"offline","type":"text","marks":[{"type":"code_inline"}]},{"text":" set to ","type":"text"},{"text":"true","type":"text","marks":[{"type":"code_inline"}]},{"text":", source ","type":"text"},{"text":"system","type":"text","marks":[{"type":"code_inline"}]},{"text":") and, on an OAuth connection, the platform's token refreshes before that (system updates of ","type":"text"},{"text":"http.auth.token.token","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"refreshToken","type":"text","marks":[{"type":"code_inline"}]},{"text":"). The errors its steps raised from then on name the cause: ","type":"text"},{"text":"invalid_grant","type":"text","marks":[{"type":"code_inline"}]},{"text":" means the provider refused the refresh token (expired or revoked), which only a person re-authorizing the connection in a browser fixes; a 401 or 403 from the application means the credential or its permissions were refused; a timeout or ","type":"text"},{"text":"ECONNREFUSED","type":"text","marks":[{"type":"code_inline"}]},{"text":" points at the network (","type":"text"},{"text":"Partner IP allow lists","type":"text","marks":[{"type":"link","attrs":{"href":"#partner-ip-allow-lists","title":null}}]},{"text":").","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Connections as concurrency queues -- throughput and governance","type":"text"}]},{"type":"paragraph","content":[{"text":"Every connection is backed by its own dedicated ","type":"text"},{"text":"FIFO queue","type":"text","marks":[{"type":"strong"}]},{"text":". Work routed through a connection lands in its queue as messages and processes first-in, first-out. A message is a unit of work for one step -- an export's run, a page of records for an import or lookup, a retry, a webhook delivery -- not a record and not a whole run, so the queue's size (","type":"text"},{"text":"queues[].size","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-1","type":"text","marks":[{"type":"code_inline"}]},{"text":" when it couldn't be read) counts messages. Two flows using the same connection ","type":"text"},{"text":"share one queue","type":"text","marks":[{"type":"strong"}]},{"text":"; a flow that touches multiple connections lands in multiple queues (one per connection). This is the mental model for throughput, rate limits, and \"why are my flows competing for capacity?\"","type":"text"}]},{"type":"paragraph","content":[{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" sets how many messages from the queue process ","type":"text"},{"text":"in parallel","type":"text","marks":[{"type":"strong"}]},{"text":" -- match the connection's ceiling to the external system's published API governance limit (if the destination permits 25 parallel requests, a ceiling of 25 runs at the limit without going over). While auto-recover is on (the default for new connections), the platform manages ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" itself, so the ceiling you set is ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":"; with auto-recover off, set ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" directly. Both are targeted changes -- no credentials needed. Queue depth is ","type":"text"},{"text":"connection-level","type":"text","marks":[{"type":"strong"}]},{"text":", owned collectively by every consumer -- never attribute a deep queue to a single flow, and treat a deep queue as an explanation (work ahead in line), not a defect. The connection document reports the current depth (","type":"text"},{"text":"queues[].size","type":"text","marks":[{"type":"code_inline"}]},{"text":"). An FTP connection can also carry ","type":"text"},{"text":"ftp.multiThreadCount","type":"text","marks":[{"type":"code_inline"}]},{"text":" (parallel transfer threads), which isn't patchable: it changes only through a full update, and a full update that leaves it out clears it.","type":"text"}]},{"type":"paragraph","content":[{"text":"The ceiling is per connection, but some systems meter per account.","type":"text","marks":[{"type":"strong"}]},{"text":" NetSuite has one concurrency pool per NetSuite account (the service tier's 5, 15, or 20, plus 10 per SuiteCloud Plus license; development and partner accounts are fixed at 5; shown at Setup > Integration > Integration Management > Integration Governance -- Celigo can't read it), shared by every connection to that account and by every caller outside Celigo. Before raising a NetSuite ceiling, total the ceilings of all connections on that account (a borrower counts under its parent), ask for the account's limit, and raise in small steps -- or put the limit on one parent and have the others borrow (","type":"text"},{"text":"Borrowing concurrency","type":"text","marks":[{"type":"link","attrs":{"href":"#borrowing-concurrency","title":null}}]},{"text":"). Over the limit, NetSuite rejects requests from every caller at once.","type":"text"}]},{"type":"paragraph","content":[{"text":"Rate limits are shared the same way.","type":"text","marks":[{"type":"strong"}]},{"text":" An API that limits requests per account or tenant counts every connection to that account together, whatever each connection's own ceiling: a second connection to the same account -- another team's flow, a new backfill -- can push the first into rate-limit errors with no change to the first. When a connection starts hitting rate limits, list the other connections with the same base URI or account and check what is running on them; to keep them under one limit, have them borrow from one parent (","type":"text"},{"text":"Borrowing concurrency","type":"text","marks":[{"type":"link","attrs":{"href":"#borrowing-concurrency","title":null}}]},{"text":").","type":"text"}]},{"type":"paragraph","content":[{"text":"Throughput symptoms almost always point back to the connection, not the flow:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Symptom","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Likely cause / fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flow hitting rate limits","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Concurrency ceiling too high for what the destination permits, or auto-recover disabled","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flow slow / not keeping up","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Concurrency ceiling too low; the system permits more parallelism than the connection uses","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Some flows starve others","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"High-volume flows share one connection's queue -- partition into separate connections (high-priority vs back-office) and set concurrency per priority","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Need to throttle a system","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Lower the ceiling on the connection serving it -- ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" while auto-recover is on, otherwise ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Auto-recover rate-limit errors","type":"text"}]},{"type":"paragraph","content":[{"text":"New connections enable ","type":"text"},{"text":"auto-recover rate limit errors","type":"text","marks":[{"type":"strong"}]},{"text":" by default, with a per-adaptor target concurrency (HTTP 25, FTP 1, most other adaptors 5; tunable per connection). On a rate-limit error (429 or equivalent), instead of piling errors into Open errors the connection throttles itself and recovers:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Drop effective concurrency to ","type":"text"},{"text":"1","type":"text","marks":[{"type":"strong"}]},{"text":" and wait ~1 minute before retrying the errored record.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Each further rate-limit error ","type":"text"},{"text":"doubles","type":"text","marks":[{"type":"strong"}]},{"text":" the wait (2, 4, 8, ... up to 1024 minutes) -- up to eleven attempts at concurrency 1, roughly 34 hours of accumulated backoff.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Once a minute passes at 1 without a rate-limit error, climb ","type":"text"},{"text":"back up","type":"text","marks":[{"type":"strong"}]},{"text":" toward the target in steps of ","type":"text"},{"text":"25% of the target","type":"text","marks":[{"type":"strong"}]},{"text":", holding a minute at each step (target 25: 1 -> 7 -> 13 -> 19 -> 25). A rate-limit error mid-recovery restarts the dance from concurrency 1.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the full sequence still hits rate-limit errors, the platform ","type":"text"},{"text":"auto-disables the setting on the connection","type":"text","marks":[{"type":"strong"}]},{"text":" -- it must be re-enabled manually, and until then rate-limit errors flow into Open errors like any other failure.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Recovered records land in the ","type":"text"},{"text":"Resolved errors","type":"text","marks":[{"type":"strong"}]},{"text":" tab (not Open errors), and the concurrency adjustments appear in the connection's ","type":"text"},{"text":"audit log","type":"text","marks":[{"type":"strong"}]},{"text":". While auto-recover is on, ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" is platform-managed -- a PUT ignores a write to it and recovery moves it toward the target -- so the lever is ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":". Changing the target stops any recovery in progress and resets concurrency to the new value. Disabling auto-recover mid-run cancels recovery: unresolved rate-limit errors go to Open errors, the target is cleared, and ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" stays wherever recovery left it -- possibly lowered -- so set it explicitly in the same change (both fields in one atomic PATCH). Re-enabling it copies the current ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" into ","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- after the platform switched it off, that's the level recovery left it at, usually 1 -- so when the user asks for it, set the target in the same PATCH. Before re-enabling it, find out why the backoff ran out -- for example, another connection to the same external account using up the shared limit (above).","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Borrowing concurrency","type":"text"}]},{"type":"paragraph","content":[{"text":"When multiple connections point at the same system but the system enforces an ","type":"text"},{"text":"account-wide","type":"text","marks":[{"type":"strong"}]},{"text":" rate limit, have them share one budget: set ","type":"text"},{"text":"_borrowConcurrencyFromConnectionId","type":"text","marks":[{"type":"code_inline"}]},{"text":" on each borrowing connection to point at a parent, and set the parent's ceiling to the system's limit (","type":"text"},{"text":"targetConcurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" while its auto-recover is on, otherwise ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":"). All borrowers draw from that shared budget (a borrower's own ","type":"text"},{"text":"concurrencyLevel","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ignored). This fits the \"partition by identity\" pattern -- different credentials or teams, one global API limit. A borrowing connection has no auto-recover toggle of its own; the ","type":"text"},{"text":"parent connection's","type":"text","marks":[{"type":"strong"}]},{"text":" auto-recover setting governs.","type":"text"}]},{"type":"paragraph","content":[{"text":"A borrower drains through the parent's queue as well as its ceiling, so a busy borrower competes with the parent's own flows and undoes a split by priority -- settle that split before choosing the parent. Borrowing is one level: a connection that borrows can't be borrowed from (422 ","type":"text"},{"text":"connection_borrows_from_another","type":"text","marks":[{"type":"code_inline"}]},{"text":"), one that others borrow from can't start borrowing (422 ","type":"text"},{"text":"connection_borrowed_by_another","type":"text","marks":[{"type":"code_inline"}]},{"text":"), and a connection can't borrow from itself. A parent can't be deleted while anything borrows from it.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Partner IP allow lists","type":"text"}]},{"type":"paragraph","content":[{"text":"When a partner restricts its server to approved IP addresses, Celigo's calls out to it (HTTP, FTP, SFTP, FTPS) time out or are refused until the partner allows Celigo's outbound ranges for the account's region, published in the Help Center article ","type":"text"},{"text":"Add integrator.io IPs to your allow list","type":"text","marks":[{"type":"link","attrs":{"href":"https://docs.celigo.com/hc/en-us/articles/115003717028","title":null}}]},{"text":":","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Region (sign-in host)","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Platform range","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Disaster-recovery range","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"US (","type":"text"},{"text":"integrator.io","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"44.204.21.0/24","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"18.246.180.128/25","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EU (","type":"text"},{"text":"eu.integrator.io","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3.79.248.128/26","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3.254.10.128/26","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CA (","type":"text"},{"text":"ca.integrator.io","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"18.99.7.224/27","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"18.99.130.96/27","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AU (","type":"text"},{"text":"au.integrator.io","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3.44.67.224/27","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"18.99.194.32/27","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"Send the partner both ranges for the region, and check the article for changes. Nothing on the Celigo side replaces that: a network policy restricts only callers coming in to Celigo -- API tokens, MCP servers, and sign-in (","type":"text"},{"text":"managing-network-policies","type":"text","marks":[{"type":"link","attrs":{"href":"../managing-network-policies/SKILL.md","title":null}}]},{"text":") -- never a connection's outbound calls. A host that can't be reached from the internet at all needs an on-premise agent instead (","type":"text"},{"text":"managing-on-premise-agents","type":"text","marks":[{"type":"link","attrs":{"href":"../managing-on-premise-agents/SKILL.md","title":null}}]},{"text":").","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Wire-level debug logging","type":"text"}]},{"type":"paragraph","content":[{"text":"When a flow fails in ways online/offline doesn't explain -- the target is reachable and credentials look fine, but records are rejected with cryptic errors or the wrong data comes back -- capture the raw traffic with the connection debugger: arm a debug window on the connection (up to about an hour), read the debug logs it captures, then disarm it.","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Captures every request/response through the connection with sensitive fields ","type":"text"},{"text":"masked","type":"text","marks":[{"type":"strong"}]},{"text":". Each entry is a header line -- the time, a trace key a request shares with its response, and the resource type and id using the connection (","type":"text"},{"text":"ping","type":"text","marks":[{"type":"code_inline"}]},{"text":" for a connection test) -- followed by the request (URL, method, headers, body) or the response. A response entry carries only headers and body, no HTTP status: read a failure from the body and from headers such as ","type":"text"},{"text":"Retry-After","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Logs appear only once data is actually moving -- not for flows queued but not yet processing. Captured logs remain available for ","type":"text"},{"text":"24 hours","type":"text","marks":[{"type":"strong"}]},{"text":" (or until cleared).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Debug is ","type":"text"},{"text":"connection-scoped","type":"text","marks":[{"type":"strong"}]},{"text":" -- it captures traffic for every flow using that connection.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Not supported","type":"text","marks":[{"type":"strong"}]},{"text":" for DynamoDB, MongoDB, or wrapper connectors; fall back to test-mode flow runs, mock data, or the destination's own logs.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"The extra per-request capture adds noticeable lag on high-volume flows (millions of records). Enable it briefly during a representative test run, or narrow the source export's criteria so a small set exercises the connection inside the debug window, then turn it off so the flow runs at full speed.","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"iClients (Shared Credential Stores)","type":"text"}]},{"type":"paragraph","content":[{"text":"An iClient is a reusable credential store that connections reference through ","type":"text"},{"text":"_iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":": an OAuth app registration (client ID and secret, scopes, token endpoints) or a cloud identity (","type":"text"},{"text":"awsIam","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"azureserviceprincipal","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"googleserviceaccount","type":"text","marks":[{"type":"code_inline"}]},{"text":"). ","type":"text"},{"text":"references/iclients.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/iclients.md","title":null}}]},{"text":" covers when you need one, how each provider is built, ","type":"text"},{"text":"custom_oauth2","type":"text","marks":[{"type":"code_inline"}]},{"text":" and JWT auth, iClient operations, and the iClient gotchas. The rules that hold on every change:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use the connector's global iClient when it has one.","type":"text","marks":[{"type":"strong"}]},{"text":" Create a custom iClient only for your own OAuth app registration or a cloud identity. A 404 reading a connector connection's iClient is Celigo's published iClient, which lives in Celigo's account -- not a deleted one.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reference it from the connection, then authorize.","type":"text","marks":[{"type":"strong"}]},{"text":" Set the connection's ","type":"text"},{"text":"_iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":" with ","type":"text"},{"text":"http.auth.oauth.useIClientFields: true","type":"text","marks":[{"type":"code_inline"}]},{"text":" for HTTP OAuth, ","type":"text"},{"text":"salesforce._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mcp.http._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"s3._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"rdbms._iClientId","type":"text","marks":[{"type":"code_inline"}]},{"text":"). An authorization-code connection then still needs the user to authorize it in a browser (the connection's Save & authorize in the Celigo UI); client-credentials and cloud-identity connections need no authorization step.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"One iClient, many connections.","type":"text","marks":[{"type":"strong"}]},{"text":" An iClient is the app, not an identity: each connection keeps its own tokens. Rotate a reissued or leaked secret by updating the iClient in place; that change reaches every connection that references it, so list them first.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"An update keeps secrets the way a connection update does.","type":"text","marks":[{"type":"strong"}]},{"text":" Send every secret field back exactly as read, ","type":"text"},{"text":"\"******\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" included, and never leave one out. A Google service account needs its full JSON key on every update (the user's change, in the UI); an Azure service principal keeps an omitted ","type":"text"},{"text":"clientSecret","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"certificate","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"validDomainNames","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" holds registrable domains","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"microsoftonline.com","type":"text","marks":[{"type":"code_inline"}]},{"text":"), never hostnames; an ","type":"text"},{"text":"[invalid_domain]","type":"text","marks":[{"type":"code_inline"}]},{"text":" failure is fixed there, not on the connection.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"A delete is refused while any connection points at the iClient","type":"text","marks":[{"type":"strong"}]},{"text":" -- a deleted connection still in the recycle bin included -- ","type":"text"},{"text":"and it is permanent","type":"text","marks":[{"type":"strong"}]},{"text":": iClients don't enter the recycle bin.","type":"text"}]}]}]}]},"metadata":{"date":"2026-11-02","name":"configuring-connections","author":"@skillopedia","source":{"stars":4,"repo_name":"ai","origin_url":"https://github.com/celigo/ai/blob/HEAD/skills/configuring-connections/SKILL.md","repo_owner":"celigo","body_sha256":"185136b292fd1c98965ad25ca9d1ac117a9b6854d22df2601de910a011896dc2","cluster_key":"6c0005d2c569ac4ac4fcf065c12bb0bea889e1ea80c34b99c4237d3a13d7ea64","clean_bundle":{"format":"clean-skill-bundle-v1","source":"celigo/ai/skills/configuring-connections/SKILL.md","text_bytes":555032,"source_commit":"2f3853ed93eece259b8c78ee74ef19035dfae052","skills_sh_rank":6271,"attachment_count":35,"text_attachments":35,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/configuring-connections/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"integrations-apis","category_label":"Integrations"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"integrations-apis","import_tag":"skills-sh-top20k-2026-11","description":"Configure Celigo connections and iClients -- credential and configuration objects that authenticate to external systems. Use when creating or editing connections, choosing auth methods, setting up OAuth, managing iClients (shared credential stores), or troubleshooting connectivity."}},"renderedAt":1793676501699}

<!-- TIER:1 -- Configuring Connections A connection is a credential and configuration object that lets Celigo communicate with an external system. Every export and import references a connection via . Connections must be created before the resources that use them. Concerns when configuring a connection: - Authentication -- choosing the right auth method (OAuth, token, basic, key-pair, certificate, etc.) and providing the correct credentials - Concurrency -- how many parallel requests Celigo can make to the target system ( ). Can be shared across connections via - Health monitoring -- ping con…