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

# Integrations

Integrations are the top-level containers that group flows, connections, exports, imports, and other resources into a logical unit. Each integration appears as a tile on the Celigo Home page.

Two flavors exist:

* **Standard integrations** — user-created containers that group custom flows.
* **Integration App installations** — created from a published connector/template, with install/uninstall steps, settings forms, editions, and optional child integrations. `_connectorId` is what identifies one. The wizard fields (`mode`, `install`, `installSteps`) also appear on a standard integration created by the UI's clone-and-install, so they do not by themselves mean Integration App.

Integrations support **Integration Lifecycle Management (ILM)**: clone an integration across environments, then use revisions (snapshot, pull, revert) to promote changes between them. Lifecycle operations carry every resource the integration contains.

### Integration schema

## The Integration object

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"components":{"schemas":{"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}}}}
````

## List integrations

> Returns all integrations in the account. Supports field projection via \`include\`/\`exclude\`.

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations":{"get":{"summary":"List integrations","description":"Returns all integrations in the account. Supports field projection via `include`/`exclude`.","operationId":"listIntegrations","tags":["Integrations"],"parameters":[{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"},{"name":"limit","in":"query","required":false,"description":"Maximum number of integrations to return per page. When more results exist, the response includes a `Link` header with a `rel=\"next\"` URL.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successfully retrieved list of integrations.","headers":{"Link":{"description":"RFC-5988 pagination links. When more pages remain, includes a `<...>; rel=\"next\"` entry;\nabsent on the final page.\n","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Integration"}}}}},"204":{"description":"No integrations exist in the account"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
````

## Create an integration

> Creates a new integration. Only \`name\` is required — the server populates all other\
> fields with defaults. Do not include \`\_connectorId\` unless you are creating an\
> Integration App installation, or \`\_templateId\` unless the integration is created from\
> a template; leave the install-wizard fields (\`mode\`, \`install\`, \`installSteps\`) to the\
> platform's installers.

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Fields that can be sent when creating or updating an integration.","required":["name"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations":{"post":{"summary":"Create an integration","description":"Creates a new integration. Only `name` is required — the server populates all other\nfields with defaults. Do not include `_connectorId` unless you are creating an\nIntegration App installation, or `_templateId` unless the integration is created from\na template; leave the install-wizard fields (`mode`, `install`, `installSteps`) to the\nplatform's installers.","operationId":"createIntegration","tags":["Integrations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"201":{"description":"Integration created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Integration"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
````

## Get an integration

> Returns the full integration object.

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}":{"get":{"summary":"Get an integration","operationId":"getIntegration","tags":["Integrations"],"description":"Returns the full integration object.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Successfully retrieved integration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Integration"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
````

## Update an integration

> Replaces the integration's mutable fields. Send the full object -- omitted fields revert to\
> defaults. GET the integration first, modify the fields you need, then PUT back. For partial\
> updates to \`settings\`, \`flowGroupings\`, or \`apiGroupings\`, prefer PATCH with JSON Patch\
> instead.

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Fields that can be sent when creating or updating an integration.","required":["name"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}":{"put":{"summary":"Update an integration","operationId":"updateIntegration","tags":["Integrations"],"description":"Replaces the integration's mutable fields. Send the full object -- omitted fields revert to\ndefaults. GET the integration first, modify the fields you need, then PUT back. For partial\nupdates to `settings`, `flowGroupings`, or `apiGroupings`, prefer PATCH with JSON Patch\ninstead.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"200":{"description":"Integration updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Integration"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
````

## Delete an integration

> Deletes an integration. The integration is soft-deleted and retained in the\
> recycle bin for 30 days before permanent removal.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-dependency-conflict":{"description":"The resource has dependents that must be deleted first. Each entry\nin the `errors` array names one blocking resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}":{"delete":{"summary":"Delete an integration","operationId":"deleteIntegration","tags":["Integrations"],"description":"Deletes an integration. The integration is soft-deleted and retained in the\nrecycle bin for 30 days before permanent removal.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"integration deleted successfully"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-dependency-conflict"}}}}}}
```

## Patch an integration

> Partially updates an integration using a JSON Patch document (RFC 6902).\
> Only the \`replace\` operation is supported, and only on the following\
> whitelisted paths:\
> \
> \| Path | Description |\
> \|------|-------------|\
> \| \`/settings\` | Integration settings object |\
> \| \`/flowGroupings\` | Flow grouping configuration |\
> \| \`/apiGroupings\` | API grouping configuration |\
> \
> All other paths are rejected with \`422\`. A successful patch returns no body, so the\
> server-assigned \`\_id\` of a grouping added through \`/flowGroupings\` or \`/apiGroupings\`\
> is only available from a follow-up \`GET\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JsonPatchRequest":{"type":"array","description":"A JSON Patch document (RFC 6902). Send an array of patch\noperations on whitelisted fields — all other paths are rejected\nwith 422.","minItems":1,"items":{"$ref":"#/components/schemas/JsonPatchOperation"}},"JsonPatchOperation":{"type":"object","description":"A single JSON Patch operation (RFC 6902).","required":["op","path"],"properties":{"op":{"type":"string","enum":["replace","add","remove"],"description":"The operation to perform."},"path":{"type":"string","description":"JSON Pointer (RFC 6901) to the field to patch. Only\nwhitelisted paths are accepted — unlisted paths return\n`422` with `\"<path> is not a whitelisted property\"`."},"value":{"description":"The new value to set. Required for `replace` and `add`, omit for `remove`."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}":{"patch":{"summary":"Patch an integration","description":"Partially updates an integration using a JSON Patch document (RFC 6902).\nOnly the `replace` operation is supported, and only on the following\nwhitelisted paths:\n\n| Path | Description |\n|------|-------------|\n| `/settings` | Integration settings object |\n| `/flowGroupings` | Flow grouping configuration |\n| `/apiGroupings` | API grouping configuration |\n\nAll other paths are rejected with `422`. A successful patch returns no body, so the\nserver-assigned `_id` of a grouping added through `/flowGroupings` or `/apiGroupings`\nis only available from a follow-up `GET`.","operationId":"patchIntegration","tags":["Integrations"],"parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonPatchRequest"}}}},"responses":{"204":{"description":"Integration patched successfully"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Clone an integration

> Creates a copy of an existing integration. When the source has registered\
> connections, remap each one via \`connectionMap\`; mapped connections are reused, not cloned.<br>

````json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"CloneRequest":{"type":"object","description":"Request body for cloning an integration.","required":["name"],"properties":{"name":{"type":"string","description":"Name for the cloned integration."},"description":{"type":"string","description":"Description for the cloned integration."},"envId":{"type":"string","format":"objectId","description":"Environment to create the clone in, taken from GET /v1/environments. Omit to\nclone within the current environment. The name has no leading underscore:\n`_envId` is ignored, and the clone is created in the current environment.\n"},"connectionMap":{"type":"object","description":"Mapping of original connection _ids to replacement connection _ids.\nKeys are source connection _ids on the original integration; values\nare target connection _ids in the destination environment.\nRequired when the source integration has registered connections — omitting it or\nsending an empty map fails with 400 `invalid_connectionMap`. Map a connection to\nitself to reuse it in the clone; omit the map when the source has none.\n","additionalProperties":{"type":"string"}}},"additionalProperties":true},"CloneResponse":{"description":"Response body for a clone operation. Some clone endpoints return the cloned resource, while others may return a list of related created resources.","oneOf":[{"title":"integration","$ref":"#/components/schemas/Integration"},{"title":"resource list","type":"array","items":{"type":"object","properties":{"model":{"type":"string","description":"Model name of the created resource (e.g., Flow, Export, Import)."},"_id":{"type":"string","format":"objectId","description":"Unique id of the created resource."},"name":{"type":"string","description":"Optional name of the created resource."}},"required":["_id"]}}]},"Integration":{"type":"object","description":"Integration object as returned by the API.","required":["_id","name","createdAt","lastModified","install","installSteps","uninstallSteps","changeEditionSteps","flowGroupings","apiGroupings","_registeredConnectionIds"],"allOf":[{"$ref":"#/components/schemas/IntegrationBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"Connections registered to this integration. Managed by the platform when users\nregister connections through the UI or the integration's registerConnection\noperation; client-sent values are ignored (PUT-verified).","items":{"type":"string","format":"objectId"}},"_registeredLookupCacheIds":{"type":"array","readOnly":true,"description":"Lookup caches registered to this integration, managed by the platform.","items":{"type":"string","format":"objectId"}},"_registeredTopicIds":{"type":"array","readOnly":true,"description":"Topics registered to this integration, so its flows can subscribe to or publish on them.\nMaintained by the platform: added through the integration's topic `register` operations,\n`POST /v1/topics` with `__integrationIds`, or automatically when a flow in the integration\nis saved with a step bound to a topic; removed by the `DELETE …/register` operation or when\nthe topic is deleted. Client-sent values are ignored (PUT-verified). Absent on integrations\nthat have never had a topic registered.","items":{"type":"string","format":"objectId"}}}}]},"IntegrationBase":{"type":"object","description":"Writable integration fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the integration.\n\nUse a short, descriptive label that helps users identify the integration in the UI."},"description":{"type":["string","null"],"maxLength":5120,"description":"Optional description of the integration's purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":["string","null"],"maxLength":51200,"description":"Long-form README content for the integration (typically Markdown).\n\nUse this to provide setup instructions, prerequisites, and operational notes."},"_connectorId":{"type":"string","format":"objectId","description":"Integration App (connector) identifier when this integration is based on an installed Integration App.\n\nIf you are not working with an Integration App installation, omit this field."},"_templateId":{"type":"string","format":"objectId","description":"Marketplace template this integration was installed from. Absent on integrations built from scratch and on\nclones. It does not make the integration an Integration App — `_connectorId` does.\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install \"cards\" an Integration App installer shows during installation — UI workflow metadata, not runtime\nconfiguration. The platform also writes it (empty) on a plain custom integration created by the UI's\nclone-and-install, so its presence does not indicate an Integration App.\n\nUnless you are explicitly modeling an install experience, omit this field.","items":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string","description":"Display name for this install card."},"description":{"type":"string","description":"Help text shown to the user for this install card."},"imageURL":{"type":"string","description":"Optional image URL to display for this install card."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created/registered by this card (if applicable)."},"installURL":{"type":"string","description":"URL to open during install (if the card is URL-based)."},"completed":{"type":["boolean","null"],"description":"When true, this card has been completed. The server also returns `null` for cards whose completion state was never set."},"installerFunction":{"type":"string","description":"Optional function name used by the platform to run install logic for this card."},"uninstallerFunction":{"type":"string","description":"Optional function name used by the platform to run uninstall logic for this card."},"options":{"type":"object","description":"Free-form options passed to the installer/uninstaller logic.","additionalProperties":true},"sourceConnection":{"type":"object","description":"Source connection metadata used to prefill or drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this card uses a template ZIP artifact."},"_stackId":{"type":"string","format":"objectId","description":"Stack identifier used by install logic (if applicable)."},"isClone":{"type":"boolean","description":"When true, this card is part of a clone workflow."},"form":{"type":"object","description":"Inline form definition used by this card (if applicable).","additionalProperties":true}}}},"mode":{"type":"string","description":"Where the integration stands in its install or uninstall wizard. The platform writes it on a plain custom\nintegration created by the UI's clone-and-install as much as on an Integration App, and leaves it set after\nthe wizard completes, so it does not indicate an Integration App (`_connectorId` does).\n\nOmit when creating an integration directly.","enum":["install","settings","uninstall"]},"settings":{"description":"Integration App settings object for this integration.","allOf":[{"description":"Integration App settings object for this integration.\n\nThese values are typically collected via `settingsForm` and then stored here. When generating values,\nprefer setting only the fields required by the form/workflow and omit unknown keys."},{"$ref":"#/components/schemas/Settings"}]},"version":{"type":["string","null"],"description":"Version of the Integration App (or template) currently installed in this integration.\nFor Integration Apps the connector's update workflow sets it; omit unless you are\nexplicitly controlling versions."},"tag":{"type":["string","null"],"description":"Legacy field for distinguishing multiple instances of the same Integration App within a single Celigo environment.\n\nOnly set this when a customer is running multiple installations of the same Integration App. Otherwise, omit this field."},"updateInProgress":{"type":"boolean","description":"When true, an Integration App update workflow is currently running. Settable via the\nAPI, but normally managed by the platform's update workflow."},"celigoAgentAutoRunMode":{"type":"boolean","description":"When true, Celigo Agent actions scoped to this integration are allowed to run automatically\nwithout a manual approval step.\n\nOmit unless you are explicitly configuring Celigo Agent behavior for this integration."},"resolvedAt":{"type":"string","format":"date-time","description":"Timestamp indicating when the most recent install/update workflow was resolved/completed.\n\nTypically system-managed; omit in normal create/update payloads."},"settingsForm":{"description":"Settings form definition for the integration.","allOf":[{"description":"Settings form definition for the integration.\n\nThis controls the UI fields shown to users to collect `settings`.\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/Form"}]},"preSave":{"description":"Pre-save hook configuration used to validate/transform settings before saving.","allOf":[{"description":"Pre-save hook configuration used to validate/transform settings before saving.\n\nUnless you are authoring/patching an Integration App definition, omit this field."},{"$ref":"#/components/schemas/PreSave"}]},"update":{"type":"object","description":"Script reference used by the platform to perform integration update logic (e.g., migration between versions).\n\nOnly include when the update workflow explicitly requires it.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the update implementation."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for the update script (if applicable)."},"function":{"type":"string","description":"Function name within the script to invoke for updates."}}},"installSteps":{"type":"array","description":"Ordered steps of the install wizard that created this integration, each marked completed as it finishes.\nWritten by the UI's clone-and-install of a plain custom integration (a `template_zip` step with `isClone`\ntrue) as well as by Integration App installers, and kept after completion — so a populated list does not\nindicate an Integration App.\n\nOmit unless you are building an installer.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"uninstallSteps":{"type":"array","description":"Ordered list of lifecycle steps used by the Integration App uninstaller.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"changeEditionSteps":{"type":"array","description":"Ordered list of steps used when changing the integration's edition/license.","items":{"type":"object","additionalProperties":true,"required":["name","type"],"properties":{"name":{"type":"string","description":"Display name for the step."},"description":{"type":"string","description":"Help text shown to the user for the step."},"imageUrl":{"type":"string","description":"Optional image URL for the step."},"completed":{"type":"boolean","description":"When true, this step has been completed."},"type":{"type":"string","description":"Step type.","enum":["connection","url","form","hidden","template_zip","stack","edition"]},"url":{"type":"string","description":"URL to open (for `type: url`)."},"form":{"type":"object","description":"Inline form definition (for `type: form`).","additionalProperties":true},"function":{"type":"string","description":"Function name to run for this step (script-based behavior)."},"initFormFunction":{"type":"string","description":"Function name used to initialize form data (for `type: form`)."},"_scriptId":{"type":"string","format":"objectId","description":"Script that contains `function`, `initFormFunction`, or `getUrlFunction`."},"sourceConnection":{"type":"object","description":"Source connection metadata used to drive install behavior.","additionalProperties":true},"templateZip":{"type":"boolean","description":"When true, this step uses a template ZIP artifact."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced/created by this step (for `type: connection`)."},"_stackId":{"type":"string","format":"objectId","description":"Stack referenced/created by this step (for `type: stack`)."},"isClone":{"type":"boolean","description":"When true, this step is being applied in a clone workflow."},"getUrlFunction":{"type":"string","description":"Function name used to compute a URL dynamically (for `type: url`)."},"options":{"type":"object","description":"Free-form options used by installer logic for this step.","additionalProperties":true}}}},"pendingLicense":{"type":["object","null"],"description":"Pending license/edition change information for the integration.\n\nThe server returns `null` when no license/edition change is pending (rather than omitting the field).\nOnly include when a license/edition change workflow explicitly requires it.","properties":{"opts":{"type":"object","description":"Free-form license options/payload.","additionalProperties":true},"_editionId":{"type":["string","null"],"format":"objectId","description":"Target edition ID for the pending license change, or `null` when cleared."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\nInvalid ids are silently dropped by the server. Omit unless creating/updating child integrations."},"childDisplayName":{"type":"string","description":"Display name used for a child integration created during installation.\n\nOmit unless creating/updating child integrations."},"initChild":{"type":"object","description":"Script reference used to initialize a child integration during installation.\n\nOnly include when the child initialization workflow explicitly requires it.","properties":{"function":{"type":"string","description":"Function name to invoke to initialize the child integration."},"_scriptId":{"type":"string","format":"objectId","description":"Script ID that contains the initChild function."},"_stackId":{"type":"string","format":"objectId","description":"Stack ID that provides runtime context for initChild (if applicable)."}}},"flowGroupings":{"type":"array","description":"UI grouping configuration that groups an integration's flows into named\nsections. Works on ANY integration — this is NOT an Integration-App-only\nfeature; a plain integration can define flow groupings too. Create groupings\nhere, then assign flows to them via `PUT /v1/flows/updateFlowGrouping`. A\ngrouping that still has member flows survives being removed from this array —\nungroup its flows first.\n\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group. At runtime, flows in the\ngroup read these values under the fixed scope key `flowGrouping` — e.g.\nthe Handlebars expression `{{{settings.flowGrouping.salesOrganization}}}`\nor the Mapper 2.0 envelope path `$.settings.flowGrouping.salesOrganization`.","additionalProperties":true},"settingsForm":{"description":"Form definition for this flow grouping's settings UI.","allOf":[{"description":"Form definition for this flow grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"apiGroupings":{"type":"array","description":"UI grouping configuration for APIs within the integration.\n\nUsed to group APIs into named sections with their own settings/settingsForm.\nWorks identically to `flowGroupings` but for API resources. Create groupings here,\nthen assign APIs to them via `PUT /v1/apis/updateApiGrouping`. A grouping that still\nhas member APIs survives being removed from this array — ungroup its APIs first.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Server-assigned grouping id."},"name":{"type":"string","description":"Display name for the API grouping section."},"settings":{"type":"object","description":"Group-level settings for APIs in this group.","additionalProperties":true},"settingsForm":{"description":"Form definition for this API grouping's settings UI.","allOf":[{"description":"Form definition for this API grouping's settings UI."},{"$ref":"#/components/schemas/Form"}]}}}},"netSuiteDistributedAdaptor":{"type":"object","description":"NetSuite distributed adaptor metadata (platform feature).\n\nOnly include if you are explicitly configuring distributed NetSuite adaptor behavior.","properties":{"accountId":{"type":"string","description":"NetSuite account identifier."},"environment":{"type":"string","description":"NetSuite environment.","enum":["production","beta","sandbox"]},"integrationId":{"type":"string","description":"Identifier used by the distributed adaptor for this integration."}}},"_sourceId":{"type":"string","format":"objectId","description":"System-assigned source identifier for the integration.\n\nTypically system-managed; omit in normal create/update payloads."},"sampleIntegration":{"type":"boolean","description":"Indicates this integration is a sample/demo integration (used for templates/examples).\n\nTypically system-managed."},"syncs":{"type":"boolean","description":"When true, the integration is a container for Celigo Sync resources — set it on\n`POST /v1/integrations` before creating syncs in it (`POST /v1/syncs` into an\nintegration without it fails with `422 integration_not_for_sync`). Fixed at creation:\n`PUT /v1/integrations/{_id}` ignores the field in both directions."},"aliases":{"type":"array","description":"Named aliases that map to specific resources within the integration.","items":{"type":"object","properties":{"alias":{"type":"string","description":"Alias name for the resource reference."},"description":{"type":"string","description":"Description of what this alias represents."},"_exportId":{"type":"string","format":"objectId","description":"Export referenced by this alias."},"_importId":{"type":"string","format":"objectId","description":"Import referenced by this alias."},"_flowId":{"type":"string","format":"objectId","description":"Flow referenced by this alias."},"_connectionId":{"type":"string","format":"objectId","description":"Connection referenced by this alias."},"_lookupCacheId":{"type":"string","format":"objectId","description":"Lookup cache referenced by this alias. Added automatically when the\ncache is registered to the integration (the alias is a slug of the\ncache name), and must be removed before the cache can be deregistered."}}}},"iLMIgnore":{"type":"object","description":"Configuration to exclude specific resources from integration lifecycle management.","additionalProperties":true}}},"Settings":{"type":"object","description":"Configuration settings that can be accessed by hooks, filters, mappings and handlebars templates at runtime.\n\nIt enables customization of the resource's logic, allowing hooks, mappings, filters, and\nhandlebars to access and apply the settings at runtime.\n\n**Usage**\n\nThe settings object can store arbitrary JSON data that you want to save with the resource.\nWhile it's often populated through a form defined in the `settingsForm` field, you can also:\n\n- Directly provide JSON settings without using a form\n- Store configuration values used by hooks and templates\n- Create resource-specific constants and parameters\n- Maintain lookup tables or mapping structures\n- Define conditional logic parameters\n\n**Accessibility**\n\nSettings are available in:\n- All handlebars fields for building dynamic payloads\n- Field mapping expressions\n- JavaScript hooks via the options object\n- Filters and transformations\n\nAt runtime, the settings objects in the step's execution chain are gathered into a\nsingle `settings` context keyed by fixed scope keys. Flow runs populate the full\nchain: `settings.integration.*`, `settings.flowGrouping.*` (the flow group the flow\nbelongs to), `settings.flow.*`, `settings.connection.*`, `settings.iClient.*`, and\nthe running step's own scope — `settings.export.*` on exports/lookups,\n`settings.import.*` on imports (the key matches the step type). Steps executing\ninside a My API or a Tool receive only the step's own scope plus\n`settings.connection.*` / `settings.iClient.*`; the integration, flowGrouping, and\nflow scopes resolve empty there. The scope key is literal — resource display names\nand settingsForm section labels are never part of the path. The segments after the\nscope mirror the stored settings JSON key path exactly: a top-level field is\n`settings.<scope>.<fieldId>`, and nested objects add one segment per JSON key\n(e.g. `settings.flowGrouping.Customer.region` when the group's settings JSON nests\n`region` under `Customer`). References without a scope key\n(e.g. `{{settings.myField}}`) resolve to empty strings.\n\n**Best practices**\n\nFor non-technical users, create a custom form instead of editing the JSON directly.\nThis provides a user-friendly interface for updating settings without requiring JSON knowledge.\n","additionalProperties":true},"Form":{"type":"object","description":"Configuration for creating user-friendly settings forms that make it easier for less technical users\nto configure integration resources.\n\n**Settings form builder**\n\nThe Settings Form Builder allows you to create or edit user-friendly fields that prompt for text entry\nor selections that will be returned as settings applied to this resource. Your forms can include any\nfield types that you see elsewhere in integrator.io, such as:\n\n- Text fields\n- Dropdown selections\n- Checkboxes\n- Radio buttons\n- Date pickers\n- Multi-select fields\n- Search fields\n\nForm fields make it much easier for less technical users to work with your integration settings by:\n\n- Providing clear labels and help text\n- Enforcing validation rules\n- Offering pre-defined selection options\n- Grouping related settings logically\n- Supporting conditional visibility\n- Creating a consistent user experience\n","properties":{"form":{"type":"object","description":"Configuration that defines the structure, fields, and behavior of the settings form.\n\nThis object contains the complete definition of the form's layout, fields, validation rules,\nand interactive behaviors. The specific structure depends on the form complexity and can include\nfield definitions, sections, conditional display logic, and default values.\n\nThe form configuration is typically created and managed through the visual Form Builder interface\nrather than edited directly as JSON.\n","properties":{"fieldMap":{"type":"object","description":"A mapping of field identifiers to their configuration objects.\nEach key in this object represents a unique field ID, and the value contains\nall the configuration settings for that specific form field.\n","additionalProperties":{"type":"object","description":"Configuration for an individual form field.\n","properties":{"id":{"type":"string","description":"Unique identifier for this field within the form.\nThis value typically matches the key in the fieldMap object.\n"},"name":{"type":"string","description":"Name of the field, used as the property name when generating the settings object\nfrom the submitted form data.\n"},"type":{"type":"string","description":"The type of form control to render for this field.\n","enum":["text","checkbox","radiogroup","relativeuri","editor","keyvalue","select","multiselect","toggle","datetime","date","exportSelect","staticMap"]},"label":{"type":"string","description":"Display label shown next to the field in the form.\n"},"description":{"type":"string","description":"Detailed explanation text that appears below the field, providing more context\nthan the label or helpText.\n"},"helpText":{"type":"string","description":"Explanatory text that appears when hovering over the help icon next to the field.\nUsed to provide additional guidance on how to use the field.\n"},"required":{"type":"boolean","description":"When true, the field must have a value before the form can be submitted.\n","default":false},"multiline":{"type":"boolean","description":"For text fields, determines whether the input should be a multi-line text area\ninstead of a single-line input.\n","default":false},"rowsMax":{"type":"integer","description":"For multiline text fields, specifies the maximum number of visible rows.\n"},"inputType":{"type":"string","description":"For text fields, specifies the HTML input type attribute to apply additional\nvalidation or specialized input behavior.\n","enum":["text","number","email","password","tel","url"]},"delimiter":{"type":"string","description":"For text fields, specifies a character to use for splitting the input into an array.\nUsed for collecting multiple values in a single text field.\n"},"mode":{"type":"string","description":"For editor fields, specifies the type of content being edited for syntax highlighting.\n","enum":["json","xml","csv","text"]},"keyName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the key input.\n"},"valueName":{"type":"string","description":"For keyvalue fields, specifies the placeholder and field name for the value input.\n"},"showDelete":{"type":"boolean","description":"For keyvalue fields, determines whether to show a delete button for each key-value pair.\n"},"doNotAllowFutureDates":{"type":"boolean","description":"For date and datetime fields, restricts selection to dates not in the future.\n"},"skipTimezoneConversion":{"type":"boolean","description":"For datetime fields, prevents automatic timezone conversion of the date value.\n"},"options":{"type":"array","description":"For fields that present choices (select, multiselect, radiogroup, toggle), defines\nthe available options.\n","items":{"anyOf":[{"title":"Option group","type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"oneOf":[{"title":"String value","type":"string"},{"title":"Label-value pair","type":"object","properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]},"description":"Array of option values/labels to display in the selection control.\n"}}},{"title":"Label-value pair","type":"object","required":["label"],"properties":{"label":{"type":"string","description":"Display text for the option.\n"},"value":{"type":"string","description":"Value to store when this option is selected.\n"}}}]}},"visibleWhen":{"type":"array","description":"Conditional display rules that determine when this field should be visible.\nIf empty or not provided, the field is always visible.\n","items":{"type":"object","properties":{"field":{"type":"string","description":"The ID of another field whose value controls the visibility of this field.\n"},"is":{"type":"array","items":{"type":["string","boolean","number","null"]},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible. Values may be strings, booleans (for\ncheckbox/toggle fields), numbers (for numeric inputs), or null.\n"}}}}}}},"layout":{"type":"object","description":"Defines how the form fields are arranged and grouped in the UI.\nThe layout can organize fields into columns, sections, or other visual groupings.\n","properties":{"type":{"type":"string","description":"The type of layout to use for the form.\n","enum":["column","collapse","box","indent","tabWithoutSave","verticalTabWithoutSave"]},"containers":{"type":"array","description":"Array of container objects that group fields or contain nested containers.\nEach container can represent a column, box, indented section, or collapsible section.\n","items":{"type":"object","properties":{"type":{"type":"string","description":"The visual style of the container.\n","enum":["indent","box","collapse"]},"label":{"type":"string","description":"The heading text displayed for this container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this container.\nEach ID must correspond to a key in the fieldMap object.\n"},"containers":{"type":"array","description":"Nested containers within this container. Allows for hierarchical organization\nof fields with different visual styles.\n","items":{"type":"object","properties":{"label":{"type":"string","description":"The heading text displayed for this nested container.\n"},"fields":{"type":"array","items":{"type":"string"},"description":"Array of field IDs that should be displayed in this nested container.\n"}}}}}}}}}},"additionalProperties":true},"init":{"type":"object","description":"Configuration for custom JavaScript initialization that executes when the form is first loaded.\n\nThis object defines a JavaScript hook that prepares the form for use, sets initial field values,\nperforms validation, or otherwise customizes the form behavior before it is displayed to the user.\n\n**Function signature**\n\nThe initialization function is invoked with a single 'options' argument containing contextual information:\n```javascript\nfunction formInit(options) {\n  // Process options and return the form object\n  return options.resource.settingsForm.form;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.resource` - The current resource being configured\n- `options.parentResource` - The parent of the current resource\n- `options.grandparentResource` - The grandparent of the current resource\n- `options.license` - For integration apps, the license provisioned to the integration\n- `options.parentLicense` - For integration apps, the parent of the license\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Dynamically generate field options based on resource configuration\n- Pre-populate default values from related resources\n- Apply conditional logic that depends on resource properties\n- Add, remove, or modify form fields based on user permissions or account settings\n- Fetch external data to populate selection options\n- Implement complex validation rules that depend on resource context\n- Create branching form experiences based on user selections\n\n**Return value**\n\nThe function must return a valid form object that the UI can render.\nThrowing an exception will signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called when the form\nis initialized and should handle any custom setup logic.\n\nThe function must follow the expected signature and return a valid form object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the initialization function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}}}},"PreSave":{"type":"object","description":"Defines a JavaScript hook that executes before the resource is saved.\n\nThis hook allows for programmatic validation, transformation, or enrichment of the\nresource itself before it is persisted. It can be used to enforce business rules,\nset derived properties, or implement cross-field validations that can't be expressed\nthrough the standard UI.\n\n**Function signature**\n\nThe preSave function is invoked with a single 'options' argument containing:\n```javascript\nfunction preSave(options) {\n  // Process options and return the modified resource\n  return options.newResource;\n}\n```\n\n**Available context**\n\nThe 'options' argument provides access to:\n- `options.newResource` - The resource being saved (with pending changes)\n- `options.oldResource` - The previous version of the resource (before changes)\n- `options.sandbox` - Boolean flag indicating whether the script is running in a sandbox environment\n\n\n**Common uses**\n\n- Enforcing complex business rules across multiple fields\n- Automatically deriving field values based on other configuration\n- Performing validation that depends on external systems or data\n- Normalizing or standardizing configuration values\n- Adding computed or derived properties\n- Implementing versioning or change tracking\n- Dynamically looking up data using the Celigo API module to enrich configuration\n\n**Return value**\n\nThe function must return the newResource object (potentially modified) to be saved.\nThrowing an exception will prevent saving and signal an error to the user.\n","properties":{"function":{"type":"string","description":"The name of the function to execute within the referenced script.\n\nThis property specifies which function to invoke from the script\nreferenced by _scriptId. The function will be called just before\nthe resource is saved.\n\nThe function must follow the expected signature and return the resource object.\n"},"_scriptId":{"type":"string","format":"objectId","description":"Reference to a predefined script resource containing the preSave function.\n\nThe referenced script should contain the function specified in the\n'function' property. This script must be accessible within the user's account\nand have appropriate permissions.\n"}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/clone":{"post":{"summary":"Clone an integration","description":"Creates a copy of an existing integration. When the source has registered\nconnections, remap each one via `connectionMap`; mapped connections are reused, not cloned.\n","operationId":"cloneIntegration","tags":["Integrations"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the integration to clone","required":true,"schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneRequest"}}}},"responses":{"201":{"description":"Integration cloned successfully. Returns a manifest of the resources the clone created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
````

## Preview cloning an integration

> Returns a preview of the resources that would be created by cloning the specified integration.\
> The response includes the integration and all transitive dependencies — flows, connections,\
> exports, imports, scripts, async helpers, lookup caches, and tools.\
> No resources are created by this endpoint.<br>

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ClonePreviewResponse":{"type":"object","description":"Preview of the resources that would be created by a clone operation.\nEach object in the `objects` array represents a resource that will be\ncloned, including the target resource and all transitive dependencies\n(connections, scripts, exports, imports, etc.).\n","properties":{"objects":{"type":"array","description":"List of resources that would be created by the clone. Always includes\nthe target resource and may include transitive dependencies such as\nconnections, scripts, exports, imports, async helpers, and lookup caches.\n","items":{"type":"object","properties":{"model":{"type":"string","description":"The model type of the resource. Observed values include\nAsyncHelper, Connection, Export, Flow, Import, Integration,\nLookupCache, Script, and Tool.\n"},"doc":{"type":"object","description":"The full resource document that would be created by the clone.","additionalProperties":true}}}},"stackRequired":{"type":"boolean","description":"Whether the clone requires a stack (connector-level) environment to proceed."},"_stackId":{"type":["string","null"],"description":"The stack id associated with the resource, or null if no stack is involved."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/clone/preview":{"get":{"summary":"Preview cloning an integration","description":"Returns a preview of the resources that would be created by cloning the specified integration.\nThe response includes the integration and all transitive dependencies — flows, connections,\nexports, imports, scripts, async helpers, lookup caches, and tools.\nNo resources are created by this endpoint.\n","operationId":"previewCloneIntegration","tags":["Integrations"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the integration to preview cloning","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Clone preview retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClonePreviewResponse"}}}},"400":{"description":"The `_id` is not a valid ObjectId.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List revisions for an integration

> Returns every revision entry (snapshots, pulls, reverts) for the integration, newest first.\
> An integration with no revision history returns an empty response (204), not \`\[]\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RevisionsResponse":{"type":"array","description":"List of revisions for an integration, newest first. Empty history returns\nan empty response rather than `[]`.","items":{"$ref":"#/components/schemas/Revision"}},"Revision":{"type":"object","description":"Integration Lifecycle Management (ILM) revision entry. Revisions capture point-in-time state of an\nintegration and drive snapshot, pull, and revert workflows across environments.","properties":{"_id":{"type":"string","format":"objectId","description":"Revision id."},"_integrationId":{"type":"string","format":"objectId","description":"Id of the integration this revision belongs to."},"_fromIntegrationId":{"type":"string","format":"objectId","description":"For `pull` / `revert` revisions, the id of the source integration the changes originated from.\nFor `snapshot` revisions this equals `_integrationId`."},"_fromIntegrationEnvId":{"type":"string","format":"objectId","description":"Environment id of the source integration."},"fromIntegrationName":{"type":"string","description":"Display name of the source integration at revision time (frozen copy)."},"type":{"type":"string","description":"Revision kind.","enum":["snapshot","pull","revert"]},"status":{"type":"string","description":"Lifecycle status. `completed` revisions are terminal; `inprogress` (pull/revert) revisions can\nbe diffed and either applied or canceled. `failed` revisions surfaced an error mid-process;\n`canceled` revisions were aborted before apply.","enum":["inprogress","completed","failed","canceled"]},"description":{"type":"string","description":"Human-entered label describing what the revision captures."},"beforeRevisionHash":{"type":"string","description":"Content hash of the integration state prior to this revision."},"transactionHash":{"type":"string","description":"Transaction hash of the revision write. Present on `pull` and `revert` revisions; absent on\nplain snapshots."},"afterRevisionHash":{"type":"string","description":"Content hash of the integration state after the revision was applied. Present on `pull` and\n`revert` revisions."},"errorFileKey":{"type":"string","readOnly":true,"description":"Storage key of the error file written when the apply step fails. Present only on `failed`\nrevisions; the file's records are read through `GET /v1/integrations/{_id}/revisions/{_revisionId}/errors`."},"_revertToRevisionId":{"type":"string","format":"objectId","description":"For `revert` revisions, the id of the target revision being reverted to."},"revertToRevisionHash":{"type":"string","description":"Content hash of the revision being reverted to — echoes `beforeRevisionHash` of the\n`_revertToRevisionId` revision."},"_createdByUserId":{"type":"string","format":"objectId","description":"User id of the creator."},"installSteps":{"type":"array","description":"Install steps associated with the revision (empty for normal snapshots; populated when the\nrevision is part of a pull/revert that requires user-facing install actions).","items":{"type":"object","additionalProperties":true}},"createdAt":{"type":"string","format":"date-time","description":"When the revision was created."},"lastModified":{"type":"string","format":"date-time","description":"Last update time of the revision record."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/revisions":{"get":{"operationId":"listIntegrationRevisions","tags":["Integrations"],"summary":"List revisions for an integration","description":"Returns every revision entry (snapshots, pulls, reverts) for the integration, newest first.\nAn integration with no revision history returns an empty response (204), not `[]`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Revision history, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionsResponse"}}}},"204":{"description":"No revisions exist for this integration."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get a revision

> Returns the full revision record. The list endpoint already surfaces every field, so this is\
> primarily useful when you have a \`\_revisionId\` in hand (e.g. from a webhook, audit log, or\
> external reference) and want to verify state without re-listing.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Revision":{"type":"object","description":"Integration Lifecycle Management (ILM) revision entry. Revisions capture point-in-time state of an\nintegration and drive snapshot, pull, and revert workflows across environments.","properties":{"_id":{"type":"string","format":"objectId","description":"Revision id."},"_integrationId":{"type":"string","format":"objectId","description":"Id of the integration this revision belongs to."},"_fromIntegrationId":{"type":"string","format":"objectId","description":"For `pull` / `revert` revisions, the id of the source integration the changes originated from.\nFor `snapshot` revisions this equals `_integrationId`."},"_fromIntegrationEnvId":{"type":"string","format":"objectId","description":"Environment id of the source integration."},"fromIntegrationName":{"type":"string","description":"Display name of the source integration at revision time (frozen copy)."},"type":{"type":"string","description":"Revision kind.","enum":["snapshot","pull","revert"]},"status":{"type":"string","description":"Lifecycle status. `completed` revisions are terminal; `inprogress` (pull/revert) revisions can\nbe diffed and either applied or canceled. `failed` revisions surfaced an error mid-process;\n`canceled` revisions were aborted before apply.","enum":["inprogress","completed","failed","canceled"]},"description":{"type":"string","description":"Human-entered label describing what the revision captures."},"beforeRevisionHash":{"type":"string","description":"Content hash of the integration state prior to this revision."},"transactionHash":{"type":"string","description":"Transaction hash of the revision write. Present on `pull` and `revert` revisions; absent on\nplain snapshots."},"afterRevisionHash":{"type":"string","description":"Content hash of the integration state after the revision was applied. Present on `pull` and\n`revert` revisions."},"errorFileKey":{"type":"string","readOnly":true,"description":"Storage key of the error file written when the apply step fails. Present only on `failed`\nrevisions; the file's records are read through `GET /v1/integrations/{_id}/revisions/{_revisionId}/errors`."},"_revertToRevisionId":{"type":"string","format":"objectId","description":"For `revert` revisions, the id of the target revision being reverted to."},"revertToRevisionHash":{"type":"string","description":"Content hash of the revision being reverted to — echoes `beforeRevisionHash` of the\n`_revertToRevisionId` revision."},"_createdByUserId":{"type":"string","format":"objectId","description":"User id of the creator."},"installSteps":{"type":"array","description":"Install steps associated with the revision (empty for normal snapshots; populated when the\nrevision is part of a pull/revert that requires user-facing install actions).","items":{"type":"object","additionalProperties":true}},"createdAt":{"type":"string","format":"date-time","description":"When the revision was created."},"lastModified":{"type":"string","format":"date-time","description":"Last update time of the revision record."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/revisions/{_revisionId}":{"get":{"operationId":"getIntegrationRevision","tags":["Integrations"],"summary":"Get a revision","description":"Returns the full revision record. The list endpoint already surfaces every field, so this is\nprimarily useful when you have a `_revisionId` in hand (e.g. from a webhook, audit log, or\nexternal reference) and want to verify state without re-listing.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_revisionId","in":"path","required":true,"description":"Revision id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Revision record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revision"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Create a snapshot revision

> Takes a point-in-time snapshot of the integration's current state and writes it to the revision\
> history. The returned revision has \`type: snapshot\` and \`status: completed\` immediately --\
> snapshots are synchronous and do not require an apply step. This is the only revision type\
> that can be created via the public API; \`pull\` and \`revert\` revisions require the Celigo UI.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RevisionCreateRequest":{"type":"object","description":"Request body for `POST /v1/integrations/{_id}/revisions/create`. Creates a `snapshot` revision of\nthe integration's current state.","properties":{"description":{"type":"string","minLength":1,"description":"Human-readable label shown in the Revisions tab. Required — the UI enforces a non-empty value\nand so does the API."}},"required":["description"]},"Revision":{"type":"object","description":"Integration Lifecycle Management (ILM) revision entry. Revisions capture point-in-time state of an\nintegration and drive snapshot, pull, and revert workflows across environments.","properties":{"_id":{"type":"string","format":"objectId","description":"Revision id."},"_integrationId":{"type":"string","format":"objectId","description":"Id of the integration this revision belongs to."},"_fromIntegrationId":{"type":"string","format":"objectId","description":"For `pull` / `revert` revisions, the id of the source integration the changes originated from.\nFor `snapshot` revisions this equals `_integrationId`."},"_fromIntegrationEnvId":{"type":"string","format":"objectId","description":"Environment id of the source integration."},"fromIntegrationName":{"type":"string","description":"Display name of the source integration at revision time (frozen copy)."},"type":{"type":"string","description":"Revision kind.","enum":["snapshot","pull","revert"]},"status":{"type":"string","description":"Lifecycle status. `completed` revisions are terminal; `inprogress` (pull/revert) revisions can\nbe diffed and either applied or canceled. `failed` revisions surfaced an error mid-process;\n`canceled` revisions were aborted before apply.","enum":["inprogress","completed","failed","canceled"]},"description":{"type":"string","description":"Human-entered label describing what the revision captures."},"beforeRevisionHash":{"type":"string","description":"Content hash of the integration state prior to this revision."},"transactionHash":{"type":"string","description":"Transaction hash of the revision write. Present on `pull` and `revert` revisions; absent on\nplain snapshots."},"afterRevisionHash":{"type":"string","description":"Content hash of the integration state after the revision was applied. Present on `pull` and\n`revert` revisions."},"errorFileKey":{"type":"string","readOnly":true,"description":"Storage key of the error file written when the apply step fails. Present only on `failed`\nrevisions; the file's records are read through `GET /v1/integrations/{_id}/revisions/{_revisionId}/errors`."},"_revertToRevisionId":{"type":"string","format":"objectId","description":"For `revert` revisions, the id of the target revision being reverted to."},"revertToRevisionHash":{"type":"string","description":"Content hash of the revision being reverted to — echoes `beforeRevisionHash` of the\n`_revertToRevisionId` revision."},"_createdByUserId":{"type":"string","format":"objectId","description":"User id of the creator."},"installSteps":{"type":"array","description":"Install steps associated with the revision (empty for normal snapshots; populated when the\nrevision is part of a pull/revert that requires user-facing install actions).","items":{"type":"object","additionalProperties":true}},"createdAt":{"type":"string","format":"date-time","description":"When the revision was created."},"lastModified":{"type":"string","format":"date-time","description":"Last update time of the revision record."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/revisions/create":{"post":{"operationId":"createIntegrationRevision","tags":["Integrations"],"summary":"Create a snapshot revision","description":"Takes a point-in-time snapshot of the integration's current state and writes it to the revision\nhistory. The returned revision has `type: snapshot` and `status: completed` immediately --\nsnapshots are synchronous and do not require an apply step. This is the only revision type\nthat can be created via the public API; `pull` and `revert` revisions require the Celigo UI.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionCreateRequest"}}}},"responses":{"201":{"description":"Snapshot revision created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revision"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Diff a pending revision

> Returns the before/after diff for a pull or revert revision. The diff is materialized on \`pull\`\
> and \`revert\` revisions and is retained on their \`completed\` state -- available for both\
> \`inprogress\` and \`completed\` pull/revert revisions. Snapshot revisions are not diffable\
> (there is no source integration to diff against), and \`canceled\` revisions drop their diff.\
> \
> The response body is a \`{before, after}\` envelope where each side is a map keyed by resource\
> type (e.g. \`flow\`, \`export\`, \`connection\`, \`api\`, \`tool\`) whose values are maps of resourceId\
> to full resource snapshot.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RevisionDiffResponse":{"type":"object","description":"Structured before/after diff for a revision. Only available while the revision is in a `pending`\nstate (e.g. a queued `pull` or `revert`). Completed snapshot revisions are read-only and return\nHTTP 400 `invalid_revision_state` — the diff is computed during the apply window, not retained.\n\nShape is the platform's internal diff document — a map of resource type → per-resource\nbefore/after blocks. Treated as an opaque envelope here; specific field layout is not guaranteed\nstable across platform versions.","additionalProperties":true},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/revisions/{_revisionId}/diff":{"get":{"operationId":"getIntegrationRevisionDiff","tags":["Integrations"],"summary":"Diff a pending revision","description":"Returns the before/after diff for a pull or revert revision. The diff is materialized on `pull`\nand `revert` revisions and is retained on their `completed` state -- available for both\n`inprogress` and `completed` pull/revert revisions. Snapshot revisions are not diffable\n(there is no source integration to diff against), and `canceled` revisions drop their diff.\n\nThe response body is a `{before, after}` envelope where each side is a map keyed by resource\ntype (e.g. `flow`, `export`, `connection`, `api`, `tool`) whose values are maps of resourceId\nto full resource snapshot.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_revisionId","in":"path","required":true,"description":"Revision id. Must be a `pull` or `revert` revision in `inprogress` or `completed` state.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Diff envelope for the pending revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionDiffResponse"}}}},"400":{"description":"Revision is not in a diffable state. Error code `invalid_revision_state`. Occurs on\nsnapshot revisions (no source to diff against), `canceled` revisions (diff dropped),\n`failed` revisions (read their cause from\n`GET /v1/integrations/{_id}/revisions/{_revisionId}/errors` instead), and\n`inprogress` revisions whose install steps haven't materialized yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List a failed revision's errors

> Returns the error records recorded while a \`pull\` or \`revert\` revision was being applied — the\
> same list the Revisions tab shows for a \`failed\` revision. Read this, not the diff, to learn why\
> a revision failed: \`GET /v1/integrations/{\_id}/revisions/{\_revisionId}/diff\` rejects \`failed\`\
> revisions with \`invalid\_revision\_state\`. Only \`failed\` revisions have error records; every\
> other state is rejected with the same \`invalid\_revision\_state\` code.\
> \
> Each record names the resource the apply step rejected. Ids inside a message use the revision's\
> change-set keys: a \`LifeCycleError\` of the form \`\<type> - \<id> references a deleted resource:\
> \<type> - \<id>.deleted\` reports that the merged document still points at an entry the same change\
> set marks \`.deleted\`. The suffix is that marker, not the resource's state in the account — the\
> resource may still exist there.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"RevisionErrorsResponse":{"type":"array","description":"Error records for one revision, oldest first.","items":{"$ref":"#/components/schemas/RevisionError"}},"RevisionError":{"type":"object","description":"One error recorded while a revision was being applied.","required":["code","message"],"properties":{"_id":{"type":"string","format":"objectId","description":"Error record id; the Revisions tab uses it to open the record's detail view."},"code":{"type":"string","description":"Error class assigned by the apply step, such as `LifeCycleError` for change-set consistency failures."},"message":{"type":"string","description":"Human-readable cause. Resource references inside it use the change set's own ids, so a\n`<id>.deleted` suffix identifies an entry of the revision, not the state of the resource in\nthe account."},"createdAt":{"type":"string","format":"date-time","description":"When the error was recorded."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/revisions/{_revisionId}/errors":{"get":{"operationId":"listIntegrationRevisionErrors","tags":["Integrations"],"summary":"List a failed revision's errors","description":"Returns the error records recorded while a `pull` or `revert` revision was being applied — the\nsame list the Revisions tab shows for a `failed` revision. Read this, not the diff, to learn why\na revision failed: `GET /v1/integrations/{_id}/revisions/{_revisionId}/diff` rejects `failed`\nrevisions with `invalid_revision_state`. Only `failed` revisions have error records; every\nother state is rejected with the same `invalid_revision_state` code.\n\nEach record names the resource the apply step rejected. Ids inside a message use the revision's\nchange-set keys: a `LifeCycleError` of the form `<type> - <id> references a deleted resource:\n<type> - <id>.deleted` reports that the merged document still points at an entry the same change\nset marks `.deleted`. The suffix is that marker, not the resource's state in the account — the\nresource may still exist there.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_revisionId","in":"path","required":true,"description":"Revision id. Must be a revision in `failed` state.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Error records for the failed revision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevisionErrorsResponse"}}}},"400":{"description":"Revision is not in `failed` state, so it has no error records. Error code\n`invalid_revision_state` — returned for `completed`, `canceled`, and `inprogress` revisions\nof every type, including snapshots.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Summarize open errors across an integration's flows

> Returns a per-flow count of currently open (unresolved) errors for every flow in the integration.\
> Flows with zero open errors still appear so callers see the full flow roster; \`lastErrorAt\` is\
> only populated when \`numError > 0\`. Entries do not contain individual error ids -- to get\
> actionable error records, drill into \`GET /v1/flows/{\_flowId}/{\_stepId}/errors\` for each flow\
> and step.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"IntegrationErrorsResponse":{"type":"array","description":"Per-flow open-error summary for an integration. One entry per flow in the integration; flows with\nzero open errors still appear so callers see the full roster. Empty integrations (no flows) return\nHTTP 204 with no body.","items":{"type":"object","properties":{"_flowId":{"type":"string","format":"objectId","description":"Id of the flow these counts apply to."},"numError":{"type":"integer","minimum":0,"description":"Count of currently open (unresolved) errors on this flow. Only\nerrors within the account's data-retention window are counted —\nolder open errors are excluded."},"lastErrorAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent open error on this flow, scoped to\nthe account's data-retention window. Omitted when `numError` is 0."}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/errors":{"get":{"operationId":"listIntegrationErrors","tags":["Integrations"],"summary":"Summarize open errors across an integration's flows","description":"Returns a per-flow count of currently open (unresolved) errors for every flow in the integration.\nFlows with zero open errors still appear so callers see the full flow roster; `lastErrorAt` is\nonly populated when `numError > 0`. Entries do not contain individual error ids -- to get\nactionable error records, drill into `GET /v1/flows/{_flowId}/{_stepId}/errors` for each flow\nand step.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Per-flow open-error summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationErrorsResponse"}}}},"204":{"description":"Integration has no flows with any reported error state."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## (Legacy) Assign open errors to a user across an integration

> Tags a batch of open errors with an assignee. Errors stay open; this does not resolve or retry\
> them. The \`email\` must resolve to a user with access to the account.\
> \
> Prefer \`PUT /v1/flows/{\_flowId}/{\_stepId}/errors/assign\` instead -- it works with a plain\
> bearer token and requires no extra headers. This integration-level endpoint requires an\
> \`integrator-ashareid\` header, and account-owner PATs have no ashare pointing at themselves, so\
> they cannot call it directly.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"IntegrationErrorsAssignRequest":{"type":"object","description":"Request body for `PUT /v1/integrations/{_id}/errors/assign`. Assigns a batch of open errors —\nacross any flow in the integration — to a user by email. Errors remain open; only the assignee\ntag changes.","properties":{"errorIds":{"type":"array","description":"Ids of open errors to assign. Obtain from the per-step endpoint\n`GET /v1/flows/{_flowId}/{_stepId}/errors` → each entry's `errorId`. The integration-level\n`GET /v1/integrations/{_id}/errors` only returns per-flow *aggregates* (no individual error\nids), so the error ids must come from the per-step endpoint. Platform caps batch size around\n~1000; chunk larger sets client-side.","minItems":1,"items":{"type":"string"}},"email":{"type":"string","format":"email","description":"Email of the account user to assign the errors to. Must match an existing user with access to\nthe account; the API does not create users implicitly and rejects unknown emails."}},"required":["errorIds","email"]},"IntegrationErrorsAssignResponse":{"type":"object","description":"Echo of the mutation — ids of errors that were reassigned. Mirrors the shape of the per-step\n`PUT /v1/flows/{_id}/{_stepId}/errors/assign` response.","properties":{"errorsToReturn":{"type":"array","description":"Error ids that were affected by the mutation.","items":{"type":"string"}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations/{_id}/errors/assign":{"put":{"operationId":"assignIntegrationErrors","tags":["Integrations"],"summary":"(Legacy) Assign open errors to a user across an integration","description":"Tags a batch of open errors with an assignee. Errors stay open; this does not resolve or retry\nthem. The `email` must resolve to a user with access to the account.\n\nPrefer `PUT /v1/flows/{_flowId}/{_stepId}/errors/assign` instead -- it works with a plain\nbearer token and requires no extra headers. This integration-level endpoint requires an\n`integrator-ashareid` header, and account-owner PATs have no ashare pointing at themselves, so\nthey cannot call it directly.","parameters":[{"name":"integrator-ashareid","in":"header","required":false,"description":"Account-share id scoping the request to a specific shared-account context. Only accepted\nwhen the bearer token's user is the `sharedWithUser` of that ashare. Not required by the\nper-step fallback — prefer that endpoint instead.","schema":{"type":"string","format":"objectId"}},{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationErrorsAssignRequest"}}}},"responses":{"200":{"description":"Errors assigned. Body echoes which ids were affected.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationErrorsAssignResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"`integrator-ashareid` is malformed (not a 24-char hex id). Error code:\n`invalid_header_value`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Either the integration is unknown, no `integrator-ashareid` was sent (code: `invalid_ref`,\nmessage: \"Integration not found.\"), or the header references a share whose `sharedWithUser`\nisn't the bearer token's user (code: `access_restricted`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## List an integration's clone family

> Returns every member of the integration's clone family -- the original plus every clone\
> (recursively, across environments). Used by ILM to decide which integrations can be pull/push\
> sources or targets for the current integration.\
> \
> This endpoint requires the \`integrator-ashareid\` header to establish a shared-account context.\
> For simpler clone-relationship lookups, the integration's own \`\_sourceId\` field points to the\
> parent it was cloned from, and \`GET /v1/integrations?\_sourceId=\<id>\` lists the children.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"CloneFamilyResponse":{"type":"array","description":"Members of an integration's clone family — the original integration plus every clone (including\nclones of clones, across environments). Used by ILM to decide which integrations can pull from or\npush to the current one.","items":{"type":"object","description":"One integration in the clone family.","properties":{"_id":{"type":"string","format":"objectId","description":"Integration id."},"name":{"type":"string","description":"Display name of the integration."},"_envId":{"type":"string","format":"objectId","description":"Environment id the integration belongs to."}},"additionalProperties":true}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations/{_id}/clonefamily":{"get":{"operationId":"listIntegrationCloneFamily","tags":["Integrations"],"summary":"List an integration's clone family","description":"Returns every member of the integration's clone family -- the original plus every clone\n(recursively, across environments). Used by ILM to decide which integrations can be pull/push\nsources or targets for the current integration.\n\nThis endpoint requires the `integrator-ashareid` header to establish a shared-account context.\nFor simpler clone-relationship lookups, the integration's own `_sourceId` field points to the\nparent it was cloned from, and `GET /v1/integrations?_sourceId=<id>` lists the children.","parameters":[{"name":"integrator-ashareid","in":"header","required":true,"description":"Account-share id that scopes the request to a specific shared-account context. The bearer\ntoken's user must be the `sharedWithUser` of this ashare.","schema":{"type":"string","format":"objectId"}},{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Clone family members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneFamilyResponse"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"Either the `integrator-ashareid` header is malformed (code: `invalid_header_value`) or it\nwas omitted entirely (code: `get_not_allowed`, \"GET resource not allowed for the given\nmodel.\").","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Integration unknown, or the `integrator-ashareid` references a share whose `sharedWithUser`\nisn't the bearer token's user (code: `access_restricted`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## List flows belonging to an integration

> Returns a bare array of full flow objects for every flow in the integration. Each element\
> is a complete flow resource, the same shape as \`GET /v1/flows/{\_id}\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/flows":{"get":{"operationId":"listIntegrationFlows","tags":["Integrations"],"summary":"List flows belonging to an integration","description":"Returns a bare array of full flow objects for every flow in the integration. Each element\nis a complete flow resource, the same shape as `GET /v1/flows/{_id}`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of flow objects to return.","schema":{"type":"integer","minimum":1}},{"name":"includeInstances","in":"query","required":false,"description":"When true, instance flows generated from abstract (multi-instance)\nflows are included in the results, which otherwise list only\nregular and abstract flows.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Array of flow objects.","content":{"application/json":{"schema":{"type":"array","description":"Bare array of full flow resource objects.","items":{"type":"object","description":"A flow resource. Same shape as returned by `GET /v1/flows/{_id}`."}}}}},"204":{"description":"Integration has no flows."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List imports belonging to an integration

> Returns a bare array of full import objects for every import in the integration. Each element\
> is a complete import resource, the same shape as \`GET /v1/imports/{\_id}\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/imports":{"get":{"operationId":"listIntegrationImports","tags":["Integrations"],"summary":"List imports belonging to an integration","description":"Returns a bare array of full import objects for every import in the integration. Each element\nis a complete import resource, the same shape as `GET /v1/imports/{_id}`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of import objects to return. **Bug:** the server returns N+1 items for a\n`limit=N` value.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Array of import objects.","content":{"application/json":{"schema":{"type":"array","description":"Bare array of full import resource objects.","items":{"type":"object","description":"An import resource. Same shape as returned by `GET /v1/imports/{_id}`."}}}}},"204":{"description":"Integration has no imports."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List exports belonging to an integration

> Returns a bare array of full export objects for every export in the integration. Each element\
> is a complete export resource, the same shape as \`GET /v1/exports/{\_id}\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/exports":{"get":{"operationId":"listIntegrationExports","tags":["Integrations"],"summary":"List exports belonging to an integration","description":"Returns a bare array of full export objects for every export in the integration. Each element\nis a complete export resource, the same shape as `GET /v1/exports/{_id}`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of export objects to return. **Bug:** the server returns N+1 items for a\n`limit=N` value.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Array of export objects.","content":{"application/json":{"schema":{"type":"array","description":"Bare array of full export resource objects.","items":{"type":"object","description":"An export resource. Same shape as returned by `GET /v1/exports/{_id}`."}}}}},"204":{"description":"Integration has no exports."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List connections belonging to an integration

> Returns a bare array of full connection objects for every connection registered to the\
> integration. Each element is a complete connection resource, the same shape as\
> \`GET /v1/connections/{\_id}\`. Unlike the flows/imports/exports sub-resource endpoints, this\
> endpoint rejects unknown integration ids with a 404.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/connections":{"get":{"operationId":"listIntegrationConnections","tags":["Integrations"],"summary":"List connections belonging to an integration","description":"Returns a bare array of full connection objects for every connection registered to the\nintegration. Each element is a complete connection resource, the same shape as\n`GET /v1/connections/{_id}`. Unlike the flows/imports/exports sub-resource endpoints, this\nendpoint rejects unknown integration ids with a 404.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of connection objects to return.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Array of connection objects.","content":{"application/json":{"schema":{"type":"array","description":"Bare array of full connection resource objects.","items":{"type":"object","description":"A connection resource. Same shape as returned by `GET /v1/connections/{_id}`."}}}}},"204":{"description":"Integration has no connections."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List async helpers belonging to an integration

> Returns a bare array of async-helper objects for every async helper registered to the\
> integration. Each element is a complete async-helper resource, the same shape as\
> \`GET /v1/asynchelpers/{\_id}\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/asynchelpers":{"get":{"operationId":"listIntegrationAsyncHelpers","tags":["Integrations"],"summary":"List async helpers belonging to an integration","description":"Returns a bare array of async-helper objects for every async helper registered to the\nintegration. Each element is a complete async-helper resource, the same shape as\n`GET /v1/asynchelpers/{_id}`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Array of async-helper objects.","content":{"application/json":{"schema":{"type":"array","description":"Bare array of full async-helper resource objects.","items":{"type":"object","description":"An async-helper resource. Same shape as returned by `GET /v1/asynchelpers/{_id}`."}}}}},"204":{"description":"Integration has no async helpers."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List account shares for an integration

> Returns an array of account-share (ashare) objects for the integration. Each entry describes a\
> user who has been granted access to the integration's owning account, along with their access\
> level and authentication metadata. Unlike other integration sub-resource list endpoints, this\
> always returns an array (an integration with no shares returns \`\[]\`).

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/ashares":{"get":{"operationId":"listIntegrationAshares","tags":["Integrations"],"summary":"List account shares for an integration","description":"Returns an array of account-share (ashare) objects for the integration. Each entry describes a\nuser who has been granted access to the integration's owning account, along with their access\nlevel and authentication metadata. Unlike other integration sub-resource list endpoints, this\nalways returns an array (an integration with no shares returns `[]`).","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Array of account-share objects.","content":{"application/json":{"schema":{"type":"array","description":"Account shares scoped to the integration.","items":{"type":"object","properties":{"_id":{"type":"string","format":"objectId","description":"Ashare id."},"accepted":{"type":"boolean","description":"When true, the shared user has accepted the invitation."},"accessLevel":{"type":"string","description":"Access level granted to the user (e.g. `administrator`, `manage`, `monitor`)."},"accountSSORequired":{"type":"boolean","description":"When true, the account requires SSO for this user."},"accountMFARequired":{"type":"boolean","description":"When true, the account requires MFA for this user."},"createdAt":{"type":"string","format":"date-time"},"lastModified":{"type":"string","format":"date-time"},"lastSignIn":{"type":"string","format":"date-time"},"isProductionAdmin":{"type":"boolean"},"sharedWithUser":{"type":"object","description":"The user this share was granted to.","properties":{"_id":{"type":"string","format":"objectId"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"lastSignIn":{"type":"string","format":"date-time"},"allowedToResetMFA":{"type":"boolean"},"accountSSOLinked":{"type":"boolean"}}}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Register a connection to an integration (by path)

> Registers a single connection to the integration by specifying the connection id in the URL\
> path. No request body is needed. To unregister, use \`DELETE\` on the same path. Alternatively,\
> use \`PUT /v1/integrations/{\_id}/connections/register\` to register by request body.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/connections/{_connectionId}/register":{"put":{"operationId":"registerConnectionToIntegration","tags":["Integrations"],"summary":"Register a connection to an integration (by path)","description":"Registers a single connection to the integration by specifying the connection id in the URL\npath. No request body is needed. To unregister, use `DELETE` on the same path. Alternatively,\nuse `PUT /v1/integrations/{_id}/connections/register` to register by request body.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_connectionId","in":"path","required":true,"description":"Connection id to register.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Connection registered successfully. No body returned."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Unregister a connection from an integration

> Removes a connection's registration from the integration. This does not delete the connection\
> itself -- it only removes it from the integration's registered-connections list.\
> \
> Fails while any resource in the integration still uses the connection. Two references\
> are known to count: any step in one of its flows, Tools, or APIs whose \`\_connectionId\`\
> is this connection -- every step is an export or import document, whatever its kind\
> (lookup, listener, AI agent, guardrail, Tool wrapper, transfer) -- and an alias on the\
> integration or one of its flows whose \`\_connectionId\` points at it. Move the steps to\
> another connection first (a whole flow at once with\
> \`PUT /v1/flows/{\_id}/replaceConnection\`; Tool and API steps through their own\
> step-level \`replaceConnection\`), remove or retarget any alias that still points at it,\
> then unregister.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/connections/{_connectionId}/register":{"delete":{"operationId":"unregisterConnectionFromIntegration","tags":["Integrations"],"summary":"Unregister a connection from an integration","description":"Removes a connection's registration from the integration. This does not delete the connection\nitself -- it only removes it from the integration's registered-connections list.\n\nFails while any resource in the integration still uses the connection. Two references\nare known to count: any step in one of its flows, Tools, or APIs whose `_connectionId`\nis this connection -- every step is an export or import document, whatever its kind\n(lookup, listener, AI agent, guardrail, Tool wrapper, transfer) -- and an alias on the\nintegration or one of its flows whose `_connectionId` points at it. Move the steps to\nanother connection first (a whole flow at once with\n`PUT /v1/flows/{_id}/replaceConnection`; Tool and API steps through their own\nstep-level `replaceConnection`), remove or retarget any alias that still points at it,\nthen unregister.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_connectionId","in":"path","required":true,"description":"Connection id to unregister.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Connection unregistered successfully. No body returned."},"400":{"description":"A resource in the integration still uses the connection -- a flow, Tool, or API\nstep bound to it (\"The connection is being actively used by the integration...\"),\nor an alias on the integration or one of its flows that points at it (\"This\nconnection is being referenced by an alias. Delete the alias before deregistering\nthe connection.\"). Error code: `not_allowed` for both.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Register a connection to an integration (by body)

> Registers a single connection to the integration by passing the connection id in the request\
> body. Alternatively, use \`PUT /v1/integrations/{\_id}/connections/{\_connectionId}/register\` to\
> register by path parameter.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/connections/register":{"put":{"operationId":"registerConnectionToIntegrationByBody","tags":["Integrations"],"summary":"Register a connection to an integration (by body)","description":"Registers a single connection to the integration by passing the connection id in the request\nbody. Alternatively, use `PUT /v1/integrations/{_id}/connections/{_connectionId}/register` to\nregister by path parameter.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["_connectionId"],"properties":{"_connectionId":{"type":"string","format":"objectId","description":"The id of the connection to register."}}}}}},"responses":{"204":{"description":"Connection registered successfully. No body returned."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List lookup caches registered to an integration

> Returns a bare array of full lookup cache objects for every cache in the integration's\
> \`\_registeredLookupCacheIds\`, sorted by \`name\`. Each element is the same shape as\
> \`GET /v1/lookupcaches/{\_id}\`. Rejects unknown integration ids with a 404.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"After":{"name":"after","in":"query","required":false,"description":"Opaque cursor for forward pagination. Pass the value from the `Link`\nresponse header (`rel=\"next\"`) to fetch the next page.","schema":{"type":"string"}}},"schemas":{"LookupCache":{"type":"object","required":["_id","_userId","createdAt","lastModified"],"description":"Lookup cache object as returned by the API.","allOf":[{"$ref":"#/components/schemas/LookupCacheBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns this lookup cache."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this lookup cache was installed from, when it originated from a template."},"_sourceId":{"type":"string","format":"objectId","readOnly":true,"description":"Origin resource ID when this cache was created by cloning or installing a template."},"size":{"type":"integer","minimum":0,"readOnly":true,"description":"Current size of the cached data in bytes. Maximum 50 MB per cache; 1 GB aggregate per environment."},"sizeInMB":{"type":"string","readOnly":true,"description":"Human-readable size rounded up to the nearest 5 MB increment.\n`\"0 MB\"` for empty caches, `\"<5 MB\"` through `\"<50 MB\"` for\nnon-empty caches, `\"50 MB\"` at the per-cache cap."},"draft":{"type":"boolean","readOnly":true,"description":"When true, this cache was created as a draft by the AI-assisted builder and has not yet been confirmed."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the draft cache expires and will be automatically deleted. Only present when `draft` is `true`."}}}]},"LookupCacheBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":5120,"description":"Purpose or contents of the cache."},"includeDataInTemplatesAndCloning":{"type":"boolean","default":false,"description":"Whether to include the cached key-value data when this cache is\nused in templates or cloned. When `false` (default), only\nmetadata transfers. Set to `true` for static reference tables."},"externalId":{"type":"string","description":"Caller-supplied identifier for cross-system correlation."}}},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/lookupcaches":{"get":{"operationId":"listIntegrationLookupCaches","tags":["Integrations"],"summary":"List lookup caches registered to an integration","description":"Returns a bare array of full lookup cache objects for every cache in the integration's\n`_registeredLookupCacheIds`, sorted by `name`. Each element is the same shape as\n`GET /v1/lookupcaches/{_id}`. Rejects unknown integration ids with a 404.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of lookup caches to return per page.","schema":{"type":"integer","minimum":1}},{"$ref":"#/components/parameters/After"}],"responses":{"200":{"description":"Array of lookup cache objects.","headers":{"Link":{"description":"RFC 5988 pagination link. Includes `<...>; rel=\"next\"` with an `after` cursor when more\ncaches remain; absent on the final page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupCache"}}}}},"204":{"description":"No lookup caches are registered to the integration."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Create a lookup cache and register it

> Creates a lookup cache exactly as \`POST /v1/lookupcaches\` does and, in the same call, adds it to\
> the integration's \`\_registeredLookupCacheIds\` and an \`aliases\[]\` entry whose \`alias\` is a slug of\
> the cache name — the same side effect as the \`register\` operations. Populate the cache afterwards\
> with \`POST /v1/lookupcaches/{\_id}/data\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request-2":{"type":"object","description":"Writable fields for creating or updating a lookup cache.","allOf":[{"$ref":"#/components/schemas/LookupCacheBase"}]},"LookupCacheBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":5120,"description":"Purpose or contents of the cache."},"includeDataInTemplatesAndCloning":{"type":"boolean","default":false,"description":"Whether to include the cached key-value data when this cache is\nused in templates or cloned. When `false` (default), only\nmetadata transfers. Set to `true` for static reference tables."},"externalId":{"type":"string","description":"Caller-supplied identifier for cross-system correlation."}}},"LookupCache":{"type":"object","required":["_id","_userId","createdAt","lastModified"],"description":"Lookup cache object as returned by the API.","allOf":[{"$ref":"#/components/schemas/LookupCacheBase"},{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"User who owns this lookup cache."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this lookup cache was installed from, when it originated from a template."},"_sourceId":{"type":"string","format":"objectId","readOnly":true,"description":"Origin resource ID when this cache was created by cloning or installing a template."},"size":{"type":"integer","minimum":0,"readOnly":true,"description":"Current size of the cached data in bytes. Maximum 50 MB per cache; 1 GB aggregate per environment."},"sizeInMB":{"type":"string","readOnly":true,"description":"Human-readable size rounded up to the nearest 5 MB increment.\n`\"0 MB\"` for empty caches, `\"<5 MB\"` through `\"<50 MB\"` for\nnon-empty caches, `\"50 MB\"` at the per-cache cap."},"draft":{"type":"boolean","readOnly":true,"description":"When true, this cache was created as a draft by the AI-assisted builder and has not yet been confirmed."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"When the draft cache expires and will be automatically deleted. Only present when `draft` is `true`."}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/lookupcaches":{"post":{"operationId":"createLookupCacheOnIntegration","tags":["Integrations"],"summary":"Create a lookup cache and register it","description":"Creates a lookup cache exactly as `POST /v1/lookupcaches` does and, in the same call, adds it to\nthe integration's `_registeredLookupCacheIds` and an `aliases[]` entry whose `alias` is a slug of\nthe cache name — the same side effect as the `register` operations. Populate the cache afterwards\nwith `POST /v1/lookupcaches/{_id}/data`.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request-2"}}}},"responses":{"201":{"description":"Created lookup cache, already registered to the integration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupCache"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Register a lookup cache to an integration (by path)

> Registers a single lookup cache to the integration by specifying the\
> lookup cache id in the URL path. No request body is needed. To\
> unregister, use \`DELETE\` on the same path. Alternatively, use\
> \`PUT /v1/integrations/{\_id}/lookupcaches/register\` to register several\
> caches at once by request body.\
> \
> Registration also adds an entry to the integration's \`aliases\[]\` when the\
> cache does not already have one: \`alias\` is a slug of the cache name\
> (lowercased, whitespace and special characters stripped, \`\_2\`/\`\_3\`/…\
> appended on collision) and \`\_lookupCacheId\` points at the cache. Scripts\
> and hooks use the alias as a stable handle for the cache, and\
> deregistering the cache is blocked until the alias is removed.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/lookupcaches/{_lookupCacheId}/register":{"put":{"operationId":"registerLookupCacheToIntegration","tags":["Integrations"],"summary":"Register a lookup cache to an integration (by path)","description":"Registers a single lookup cache to the integration by specifying the\nlookup cache id in the URL path. No request body is needed. To\nunregister, use `DELETE` on the same path. Alternatively, use\n`PUT /v1/integrations/{_id}/lookupcaches/register` to register several\ncaches at once by request body.\n\nRegistration also adds an entry to the integration's `aliases[]` when the\ncache does not already have one: `alias` is a slug of the cache name\n(lowercased, whitespace and special characters stripped, `_2`/`_3`/…\nappended on collision) and `_lookupCacheId` points at the cache. Scripts\nand hooks use the alias as a stable handle for the cache, and\nderegistering the cache is blocked until the alias is removed.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_lookupCacheId","in":"path","required":true,"description":"Lookup cache id to register.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Lookup cache registered successfully. No body returned."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Unregister a lookup cache from an integration

> Removes a lookup cache's registration from the integration. This does\
> not delete the lookup cache itself — it only removes it from the\
> integration's \`\_registeredLookupCacheIds\` list. Fails when the cache is\
> not registered on the integration, when a flow step in the integration\
> still references it, or when an alias on the integration (or one of its\
> flows) still points at it — including the alias that registration itself\
> created. Remove the flow-step references and the alias (update the\
> \`aliases\` array on the integration or flow) first, then retry.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/lookupcaches/{_lookupCacheId}/register":{"delete":{"operationId":"unregisterLookupCacheFromIntegration","tags":["Integrations"],"summary":"Unregister a lookup cache from an integration","description":"Removes a lookup cache's registration from the integration. This does\nnot delete the lookup cache itself — it only removes it from the\nintegration's `_registeredLookupCacheIds` list. Fails when the cache is\nnot registered on the integration, when a flow step in the integration\nstill references it, or when an alias on the integration (or one of its\nflows) still points at it — including the alias that registration itself\ncreated. Remove the flow-step references and the alias (update the\n`aliases` array on the integration or flow) first, then retry.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_lookupCacheId","in":"path","required":true,"description":"Lookup cache id to unregister.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Lookup cache unregistered successfully. No body returned."},"400":{"description":"The cache is not registered on this integration (\"The lookup cache\nwhich you are trying to deregister is not registered on the\nintegration.\"), is still referenced by a flow step in the\nintegration (\"The lookup cache is being actively used by a flow\nstep in this integration...\"), or is still referenced by an alias\n(\"The lookup cache is referenced by an alias in this integration.\nRemove the alias before deregistering.\"). Error code: `not_allowed`\nfor all three.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Register lookup caches to an integration (by body)

> Registers one or more lookup caches to the integration, adding them to\
> its \`\_registeredLookupCacheIds\` list. The request body is a bare JSON\
> array of lookup cache ids; duplicates are collapsed. Alternatively, use\
> \`PUT /v1/integrations/{\_id}/lookupcaches/{\_lookupCacheId}/register\` to\
> register a single cache by path parameter.\
> \
> Registration also adds an entry to the integration's \`aliases\[]\` for each\
> newly registered cache that does not already have one: \`alias\` is a slug\
> of the cache name (lowercased, whitespace and special characters stripped,\
> \`\_2\`/\`\_3\`/… appended on collision) and \`\_lookupCacheId\` points at the\
> cache. Scripts and hooks use the alias as a stable handle for the cache,\
> and deregistering the cache is blocked until the alias is removed.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/lookupcaches/register":{"put":{"operationId":"registerLookupCachesToIntegration","tags":["Integrations"],"summary":"Register lookup caches to an integration (by body)","description":"Registers one or more lookup caches to the integration, adding them to\nits `_registeredLookupCacheIds` list. The request body is a bare JSON\narray of lookup cache ids; duplicates are collapsed. Alternatively, use\n`PUT /v1/integrations/{_id}/lookupcaches/{_lookupCacheId}/register` to\nregister a single cache by path parameter.\n\nRegistration also adds an entry to the integration's `aliases[]` for each\nnewly registered cache that does not already have one: `alias` is a slug\nof the cache name (lowercased, whitespace and special characters stripped,\n`_2`/`_3`/… appended on collision) and `_lookupCacheId` points at the\ncache. Scripts and hooks use the alias as a stable handle for the cache,\nand deregistering the cache is blocked until the alias is removed.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","description":"Lookup cache ids to register.","items":{"type":"string","format":"objectId"}}}}},"responses":{"204":{"description":"Lookup caches registered successfully. No body returned."},"400":{"description":"An entry in the array is not a valid ObjectId.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List topics registered to an integration

> Returns a bare array of full topic objects for every topic in the integration's\
> \`\_registeredTopicIds\`, sorted by \`name\`. Each element is the same shape as\
> \`GET /v1/topics/{\_id}\`. Rejects unknown integration ids with a 404. The \`externalId\` filter of\
> \`GET /v1/topics\` is not applied here.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"After":{"name":"after","in":"query","required":false,"description":"Opaque cursor for forward pagination. Pass the value from the `Link`\nresponse header (`rel=\"next\"`) to fetch the next page.","schema":{"type":"string"}}},"schemas":{"Topic":{"type":"object","description":"Topic as returned by the API.","required":["_id","_userId","name","retentionMs","createdAt","lastModified"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the topic. Topic exports and imports bind to it through\n`topic._topicId`, and it is the `_topicId` used by every `/v1/topics/{_id}/…` endpoint."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner whose license and topic quota the topic counts against."},"name":{"type":"string","maxLength":200,"description":"Display name shown in the UI. Empty when the topic was created without one; not unique, so\nuse `_id` to identify a topic."},"description":{"type":["string","null"],"maxLength":5120,"description":"What the topic carries and which flows consume it. Absent or null when never set."},"retentionMs":{"type":"integer","minimum":3600000,"maximum":7776000000,"default":604800000,"description":"How long a published message stays readable, in milliseconds, before it is dropped from the\nstream whether or not a listener consumed it. The week-long default applies when the topic was\ncreated without one."},"externalId":{"type":"string","maxLength":1024,"description":"Caller-chosen key set at creation or update. Present only when it was supplied; filter the\nlist with `GET /v1/topics?externalId=…`."},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration App installation that owns the topic. Present only on topics created by an\nIntegration App; absent on topics you create directly, which are shared across integrations\nthrough `_registeredTopicIds` instead."},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration App (connector) that installed the topic. Present only on connector-managed\ntopics, which the connector — not the user — registers and deregisters."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template the topic was installed from. Present only when it originated from a template."},"_sourceId":{"type":"string","format":"objectId","readOnly":true,"description":"Topic this one was cloned or installed from. Present only on copies."},"draft":{"type":"boolean","description":"When true, the topic is an unconfirmed draft (created with `draft: true`, typically by\nthe AI-assisted builder) that auto-deletes at `draftExpiresAt`. Absent on ordinary\ntopics and once a `PUT` with `draft: false` promotes the draft."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when an unconfirmed draft is deleted automatically — 48 hours after\ncreation. Present only while `draft` is true; cleared together with it."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was last updated by PUT or PATCH."},"deletedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was moved to the recycle bin. Present only on the copy returned by\n`GET /v1/recycleBinTTL/topics/{_id}`; deleted topics are hidden from every other endpoint."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/topics":{"get":{"operationId":"listIntegrationTopics","tags":["Integrations"],"summary":"List topics registered to an integration","description":"Returns a bare array of full topic objects for every topic in the integration's\n`_registeredTopicIds`, sorted by `name`. Each element is the same shape as\n`GET /v1/topics/{_id}`. Rejects unknown integration ids with a 404. The `externalId` filter of\n`GET /v1/topics` is not applied here.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of topics to return per page.","schema":{"type":"integer","minimum":1}},{"$ref":"#/components/parameters/After"}],"responses":{"200":{"description":"Array of topic objects.","headers":{"Link":{"description":"RFC 5988 pagination link. Includes `<...>; rel=\"next\"` with an `after` cursor when more\ntopics remain; absent on the final page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Topic"}}}}},"204":{"description":"No topics are registered to the integration."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Create a topic and register it

> Creates a topic exactly as \`POST /v1/topics\` does and, in the same call, adds it to the\
> integration's \`\_registeredTopicIds\`. Use this when the topic is being built for one integration's\
> flows; to share a topic across several integrations, create it with \`POST /v1/topics\` and\
> register it on each with the \`register\` operations.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request-3":{"type":"object","description":"Writable fields for creating or updating a topic.","required":["name"],"properties":{"name":{"type":"string","maxLength":200,"description":"Display name shown in the UI and recorded as `deletedInfo.name` on audit entries. Names need\nnot be unique — exports and imports bind to the topic id, so renaming never breaks a\nsubscription. Script tags and other unsafe HTML are stripped on save."},"description":{"type":["string","null"],"maxLength":5120,"description":"What the topic carries and which flows consume it. Shown in the UI only; it plays no part in\nrouting. Send null to clear a previous value."},"retentionMs":{"type":"integer","minimum":3600000,"maximum":7776000000,"default":604800000,"description":"How long a published message stays readable, in milliseconds, before it is dropped from the\nstream whether or not a listener consumed it. The default keeps a week of messages, enough for\na listener that is paused over a weekend to catch up; the ceiling is further capped by the\naccount license's `topics.retentionCeilingDays`. Changing it on an existing topic\nre-configures the stream, so messages older than the new window are no longer retained."},"externalId":{"type":"string","maxLength":1024,"description":"Caller-chosen key for finding the topic again without storing its id — filter the list with\n`GET /v1/topics?externalId=…`. Integration Apps use it to locate a topic across installs."},"draft":{"type":"boolean","description":"When true, the topic is a draft that auto-deletes 48 hours after creation\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it, and a PUT that omits it leaves an existing draft as is —\nthe one field the whole-document PUT does not clear."},"__integrationIds":{"type":"array","maxItems":100,"items":{"type":"string","format":"objectId"},"description":"Integrations to register the new topic on immediately after creation, so flows in those\nintegrations can subscribe to it. Honored only on `POST /v1/topics` (ignored on PUT), never\npersisted, and not echoed back. Ids are validated before the topic is saved; registration\nruns after the save, and per-integration failures are reported in\n`__failedIntegrationRegistrations` on the 201 response without rolling back the new topic."}}},"Topic":{"type":"object","description":"Topic as returned by the API.","required":["_id","_userId","name","retentionMs","createdAt","lastModified"],"properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the topic. Topic exports and imports bind to it through\n`topic._topicId`, and it is the `_topicId` used by every `/v1/topics/{_id}/…` endpoint."},"_userId":{"type":"string","format":"objectId","readOnly":true,"description":"Account owner whose license and topic quota the topic counts against."},"name":{"type":"string","maxLength":200,"description":"Display name shown in the UI. Empty when the topic was created without one; not unique, so\nuse `_id` to identify a topic."},"description":{"type":["string","null"],"maxLength":5120,"description":"What the topic carries and which flows consume it. Absent or null when never set."},"retentionMs":{"type":"integer","minimum":3600000,"maximum":7776000000,"default":604800000,"description":"How long a published message stays readable, in milliseconds, before it is dropped from the\nstream whether or not a listener consumed it. The week-long default applies when the topic was\ncreated without one."},"externalId":{"type":"string","maxLength":1024,"description":"Caller-chosen key set at creation or update. Present only when it was supplied; filter the\nlist with `GET /v1/topics?externalId=…`."},"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration App installation that owns the topic. Present only on topics created by an\nIntegration App; absent on topics you create directly, which are shared across integrations\nthrough `_registeredTopicIds` instead."},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Integration App (connector) that installed the topic. Present only on connector-managed\ntopics, which the connector — not the user — registers and deregisters."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template the topic was installed from. Present only when it originated from a template."},"_sourceId":{"type":"string","format":"objectId","readOnly":true,"description":"Topic this one was cloned or installed from. Present only on copies."},"draft":{"type":"boolean","description":"When true, the topic is an unconfirmed draft (created with `draft: true`, typically by\nthe AI-assisted builder) that auto-deletes at `draftExpiresAt`. Absent on ordinary\ntopics and once a `PUT` with `draft: false` promotes the draft."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when an unconfirmed draft is deleted automatically — 48 hours after\ncreation. Present only while `draft` is true; cleared together with it."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was last updated by PUT or PATCH."},"deletedAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the topic was moved to the recycle bin. Present only on the copy returned by\n`GET /v1/recycleBinTTL/topics/{_id}`; deleted topics are hidden from every other endpoint."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/topics":{"post":{"operationId":"createTopicOnIntegration","tags":["Integrations"],"summary":"Create a topic and register it","description":"Creates a topic exactly as `POST /v1/topics` does and, in the same call, adds it to the\nintegration's `_registeredTopicIds`. Use this when the topic is being built for one integration's\nflows; to share a topic across several integrations, create it with `POST /v1/topics` and\nregister it on each with the `register` operations.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request-3"}}}},"responses":{"201":{"description":"Created topic, already registered to the integration.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Topic"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"The topic body failed validation — the same codes as `POST /v1/topics`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Register a topic to an integration (by path)

> Adds a single topic to the integration's \`\_registeredTopicIds\` so flows in the integration can\
> subscribe to or publish on it. No request body is needed; registering an already-registered topic\
> succeeds without duplicating it. To unregister, use \`DELETE\` on the same path; to register several\
> topics at once, use \`PUT /v1/integrations/{\_id}/topics/register\`.\
> \
> Registration also happens automatically when a flow in the integration is saved with a step\
> bound to the topic. Unlike lookup caches, registering a topic adds no \`aliases\[]\` entry.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/topics/{_topicId}/register":{"put":{"operationId":"registerTopicToIntegration","tags":["Integrations"],"summary":"Register a topic to an integration (by path)","description":"Adds a single topic to the integration's `_registeredTopicIds` so flows in the integration can\nsubscribe to or publish on it. No request body is needed; registering an already-registered topic\nsucceeds without duplicating it. To unregister, use `DELETE` on the same path; to register several\ntopics at once, use `PUT /v1/integrations/{_id}/topics/register`.\n\nRegistration also happens automatically when a flow in the integration is saved with a step\nbound to the topic. Unlike lookup caches, registering a topic adds no `aliases[]` entry.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_topicId","in":"path","required":true,"description":"Topic id to register.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Topic registered successfully. No body returned."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"The integration does not exist, or the topic does not exist in this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Unregister a topic from an integration

> Removes a topic's registration from the integration. This does not delete the topic — it only\
> removes it from the integration's \`\_registeredTopicIds\`. Fails when the topic is not registered\
> on the integration, or while any flow step in the integration (an export or import with\
> \`topic.\_topicId\` set) still uses it. Repoint or delete those steps first, then retry.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/{_id}/topics/{_topicId}/register":{"delete":{"operationId":"unregisterTopicFromIntegration","tags":["Integrations"],"summary":"Unregister a topic from an integration","description":"Removes a topic's registration from the integration. This does not delete the topic — it only\nremoves it from the integration's `_registeredTopicIds`. Fails when the topic is not registered\non the integration, or while any flow step in the integration (an export or import with\n`topic._topicId` set) still uses it. Repoint or delete those steps first, then retry.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}},{"name":"_topicId","in":"path","required":true,"description":"Topic id to unregister.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Topic unregistered successfully. No body returned."},"400":{"description":"The topic is not registered on this integration (\"The topic which you are trying to\nderegister is not registered on the integration.\"), or a flow step in the integration still\nuses it (\"The topic is being actively used by a step in this integration…\"). Error code:\n`not_allowed` for both.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Register topics to an integration (by body)

> Adds one or more topics to the integration's \`\_registeredTopicIds\`. The request body is a bare\
> JSON array of topic ids; duplicates and already-registered ids are collapsed, and an empty array\
> is accepted as a no-op. Every id must name a topic in this account or nothing is registered.\
> Alternatively, use \`PUT /v1/integrations/{\_id}/topics/{\_topicId}/register\` to register a single\
> topic by path parameter.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations/{_id}/topics/register":{"put":{"operationId":"registerTopicsToIntegration","tags":["Integrations"],"summary":"Register topics to an integration (by body)","description":"Adds one or more topics to the integration's `_registeredTopicIds`. The request body is a bare\nJSON array of topic ids; duplicates and already-registered ids are collapsed, and an empty array\nis accepted as a no-op. Every id must name a topic in this account or nothing is registered.\nAlternatively, use `PUT /v1/integrations/{_id}/topics/{_topicId}/register` to register a single\ntopic by path parameter.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","description":"Topic ids to register.","items":{"type":"string","format":"objectId"}}}}},"responses":{"204":{"description":"Topics registered successfully. No body returned."},"400":{"description":"The body is not a JSON array (\"Maximum batch size is …\", code `batch_size_exceeded`), or an\nentry is not a valid ObjectId (\"Please provide a valid _topicId.\", code `invalid_ref`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"The integration does not exist, or one of the topics does not exist in this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get integration tree metadata

> Returns structural metadata for the integration and its child integrations. The response\
> includes install steps, flow groupings, API groupings, registered connection ids, uninstall\
> steps, and change-edition steps, plus a \`childIntegrations\` array with the same structure for\
> each child. Primarily useful for Integration App integrations that have install/uninstall steps\
> and child integrations.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/tree/metadata":{"get":{"operationId":"getIntegrationTreeMetadata","tags":["Integrations"],"summary":"Get integration tree metadata","description":"Returns structural metadata for the integration and its child integrations. The response\nincludes install steps, flow groupings, API groupings, registered connection ids, uninstall\nsteps, and change-edition steps, plus a `childIntegrations` array with the same structure for\neach child. Primarily useful for Integration App integrations that have install/uninstall steps\nand child integrations.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Integration tree metadata.","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"type":"object","description":"Metadata for the integration itself, including install steps, flow groupings,\nAPI groupings, registered connection ids, uninstall steps, and change-edition steps."},"childIntegrations":{"type":"array","description":"Metadata for child integrations (empty array if none).","items":{"type":"object"}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Resume an Integration App integration

> Resumes a paused Integration App integration. Requires that the integration belongs to an\
> Integration App. No request body is needed.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/resume":{"put":{"operationId":"resumeIntegration","tags":["Integrations"],"summary":"Resume an Integration App integration","description":"Resumes a paused Integration App integration. Requires that the integration belongs to an\nIntegration App. No request body is needed.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Integration resumed successfully."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"Integration does not belong to an Integration App. Error code: `invalid_ref`, message:\n\"doesnot belongs to any Integration App.\"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Change the edition of an Integration App integration

> Triggers an edition change for an Integration App integration that has a \`changeEdition\`\
> function configured. Requires the integration to belong to an Integration App with edition\
> support.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/changeEdition":{"post":{"operationId":"changeIntegrationEdition","tags":["Integrations"],"summary":"Change the edition of an Integration App integration","description":"Triggers an edition change for an Integration App integration that has a `changeEdition`\nfunction configured. Requires the integration to belong to an Integration App with edition\nsupport.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Edition change initiated successfully."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"Integration does not belong to an Integration App with changeEdition support. Error code:\n`invalid_integration_app`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Initialize a child integration

> Initializes a child integration under an Integration App parent. Requires the parent integration\
> to belong to an Integration App with an init script configured.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/initChild":{"post":{"operationId":"initChildIntegration","tags":["Integrations"],"summary":"Initialize a child integration","description":"Initializes a child integration under an Integration App parent. Requires the parent integration\nto belong to an Integration App with an init script configured.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id (the parent Integration App integration).","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Child integration initialized successfully."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"Integration App does not have a valid init script. Error code: `invalid_ref`, message:\n\"Script fields invalid or not found.\"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Detach the license from an integration

> Detaches the license from an integration. Idempotent -- calling it on an integration that\
> already has no license attached is a no-op. No request body is needed.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/detachLicense":{"put":{"operationId":"detachIntegrationLicense","tags":["Integrations"],"summary":"Detach the license from an integration","description":"Detaches the license from an integration. Idempotent -- calling it on an integration that\nalready has no license attached is a no-op. No request body is needed.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"License detached (or was already detached). No body returned."},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List available ILM ignore fields

> Returns the catalog of \*available\* fields that can be ignored when pulling changes between\
> related integrations. Keys are lowercase resource types (\`integration\`, \`flow\`, \`export\`,\
> \`import\`, \`connection\`, \`script\`, ...); values are arrays of dot-path field names that can be\
> excluded from an ILM pull/revert. The key set is platform-driven — treat the response, not\
> the example list, as the authoritative catalog.\
> \
> This endpoint requires the \`integrator-ashareid\` header to establish a shared-account context.\
> The current ignore configuration lives on the integration's \`iLMIgnore\` field (readable via\
> \`GET /v1/integrations/{\_id}\`); this endpoint only returns the menu of what \*can\* be ignored.\
> To change the configuration, PATCH the integration with\
> \`\[{op:"replace", path:"/iLMIgnore", value:{...}}]\`.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ILMIgnoreResponse":{"type":"object","description":"Catalog of resource-type → field-path lists that are *available* to be ignored during ILM pulls\nand reverts. This is the full menu of what can be configured — to see the current ignore\nconfiguration, read the `iLMIgnore` field on the integration itself via\n`GET /v1/integrations/{_id}`.\n\nKeys are lowercase resource type names (e.g. `integration`, `flow`, `export`, `import`,\n`connection`, `script`). Each value is an array of dot-path strings naming fields that can be\nexcluded. Only resource types that have configurable ignores appear as keys.","additionalProperties":{"type":"array","description":"Field paths (dotted) that can be ignored for this resource type.","items":{"type":"string"}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations/{_id}/iLMIgnore":{"get":{"operationId":"getIntegrationILMIgnoreFields","tags":["Integrations"],"summary":"List available ILM ignore fields","description":"Returns the catalog of *available* fields that can be ignored when pulling changes between\nrelated integrations. Keys are lowercase resource types (`integration`, `flow`, `export`,\n`import`, `connection`, `script`, ...); values are arrays of dot-path field names that can be\nexcluded from an ILM pull/revert. The key set is platform-driven — treat the response, not\nthe example list, as the authoritative catalog.\n\nThis endpoint requires the `integrator-ashareid` header to establish a shared-account context.\nThe current ignore configuration lives on the integration's `iLMIgnore` field (readable via\n`GET /v1/integrations/{_id}`); this endpoint only returns the menu of what *can* be ignored.\nTo change the configuration, PATCH the integration with\n`[{op:\"replace\", path:\"/iLMIgnore\", value:{...}}]`.","parameters":[{"name":"integrator-ashareid","in":"header","required":true,"description":"Account-share id that scopes the request to a specific shared-account context. The bearer\ntoken's user must be the `sharedWithUser` of this ashare.","schema":{"type":"string","format":"objectId"}},{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Available ignore fields per resource type.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ILMIgnoreResponse"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"description":"Either the `integrator-ashareid` header is malformed (code: `invalid_header_value`) or it\nwas omitted entirely (code: `get_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Integration unknown, or the `integrator-ashareid` references a share whose `sharedWithUser`\nisn't the bearer token's user (code: `access_restricted`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a downloadable template for an integration

> Packages the integration as an installable template and returns a signed\
> S3 URL where the template \`.zip\` can be downloaded. The URL is\
> pre-signed and short-lived (it expires shortly after issuance), so fetch\
> the file promptly after calling this endpoint.\
> \
> The downloaded \`.zip\` is the same artifact used to install the integration\
> as a template into another account.

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/integrations/{_id}/template":{"get":{"operationId":"getIntegrationTemplate","tags":["Integrations"],"summary":"Get a downloadable template for an integration","description":"Packages the integration as an installable template and returns a signed\nS3 URL where the template `.zip` can be downloaded. The URL is\npre-signed and short-lived (it expires shortly after issuance), so fetch\nthe file promptly after calling this endpoint.\n\nThe downloaded `.zip` is the same artifact used to install the integration\nas a template into another account.","parameters":[{"name":"_id","in":"path","required":true,"description":"Integration id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Signed download URL for the integration template zip.","content":{"application/json":{"schema":{"type":"object","properties":{"signedURL":{"type":"string","description":"Pre-signed, short-lived S3 URL to download the template `.zip`."},"key":{"type":"string","description":"S3 object key for the generated template `.zip`."}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List dependencies of an integration

> Returns the set of resources that depend on the specified resource.\
> The response is an object whose keys are dependent-resource types\
> (e.g. \`flows\`, \`imports\`) and whose values are arrays of dependency\
> entries. An empty object \`{}\` means no other resources depend on the\
> target (also returned for a well-formatted but nonexistent id).

```json
{"openapi":"3.2.0","info":{"title":"Integrations","version":"1.0.0"},"tags":[{"name":"Integrations","description":"Integrations are the top-level containers that group flows, connections, exports,\nimports, and other resources into a logical unit. Each integration appears as a tile\non the Celigo Home page.\n\nTwo flavors exist:\n- **Standard integrations** — user-created containers that group custom flows.\n- **Integration App installations** — created from a published connector/template,\n  with install/uninstall steps, settings forms, editions, and optional child\n  integrations. `_connectorId` is what identifies one. The wizard fields (`mode`,\n  `install`, `installSteps`) also appear on a standard integration created by the\n  UI's clone-and-install, so they do not by themselves mean Integration App.\n\nIntegrations support **Integration Lifecycle Management (ILM)**: clone an integration\nacross environments, then use revisions (snapshot, pull, revert) to promote changes\nbetween them. Lifecycle operations carry every resource the integration contains.\n\n## Integration schema\n\n{% openapi-schemas spec=\"integration\" schemas=\"Integration\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"DependencyResponse":{"type":"object","description":"Map of dependent-resource types to arrays of dependency entries.\nKeys are plural resource type strings (e.g. `flows`, `imports`,\n`connections`). An empty object `{}` means no dependents.\n","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/DependencyEntry"}}},"DependencyEntry":{"type":"object","description":"A single resource that depends on the queried resource.","properties":{"id":{"type":"string","description":"Unique identifier of the dependent resource."},"name":{"type":"string","description":"Display name of the dependent resource."},"type":{"type":"string","description":"Sub-type of the dependent resource when its collection distinguishes one, such as\n`stream` for a listener export. Only present for resource types that carry a `type`."},"paths":{"type":"array","description":"Dot-notation paths within the dependent resource that reference\nthe target resource. `[*]` denotes array elements.","items":{"type":"string"}},"accessLevel":{"type":"string","description":"The caller's access level on the dependent resource."},"dependencyIds":{"type":"object","description":"Map of resource types to arrays of IDs that this dependent\nresource references on the target. Keys are singular or plural\nresource type strings; values are arrays of ID strings.","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["id","name","paths","accessLevel","dependencyIds"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/integrations/{_id}/dependencies":{"get":{"operationId":"listIntegrationDependencies","tags":["Integrations"],"summary":"List dependencies of an integration","description":"Returns the set of resources that depend on the specified resource.\nThe response is an object whose keys are dependent-resource types\n(e.g. `flows`, `imports`) and whose values are arrays of dependency\nentries. An empty object `{}` means no other resources depend on the\ntarget (also returned for a well-formatted but nonexistent id).","parameters":[{"name":"_id","in":"path","required":true,"description":"Resource ID.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Dependency map. Keys are resource-type strings; values are arrays\nof dependency entries. Returns `{}` when no dependents exist.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DependencyResponse"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```
