# Integrations

## List integrations

> Returns a list of all integrations configured in the account.

````json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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** on supported list endpoints: the server\nreturns a minimal identity set for each record (`_id`, `name`, plus a\nresource-specific always-on set like `adaptorType` on exports/imports,\nor richer defaults on `ashares`, `audit`, `httpconnectors`, `transfers`,\netc.) and adds any listed fields that exist on the record. Listed fields\nthe record doesn't carry are silently dropped.\n\nDot notation is supported for projecting nested sub-fields — e.g.\n`include=ftp.directoryPath` on `/v1/exports` returns just that nested\nfield inside `ftp` for FTP-type exports (and omits `ftp` entirely for\nnon-FTP exports).\n\nRules:\n- Value regex is `{a-z A-Z . _}` (letters, dots, underscores) plus the\n  comma separator; digits are also accepted in practice. Any other\n  character returns **400 `invalid_query_params`**.\n- Empty value (`include=`) or bare `include` is ignored — the full\n  default record is returned.\n- `include` and `exclude` are **mutually exclusive**. Passing both\n  returns **400 `invalid_query_params`**: *\"Please provide either\n  include or exclude param in the request query and not both.\"*\n- Array-bracket syntax (`include[]=...`) is not supported and can return\n  a 500.\n- Only list endpoints honor projection — on GET-by-id the parameter is\n  silently ignored.\n- A small set of list endpoints explicitly reject both `include` and\n  `exclude` with **400 `invalid_query_params`** and a message of the form\n  *\"Include or exclude query params are not applicable for `<resource>`\n  resource.\"* Known rejections: `/v1/ediprofiles`, `/v1/environments`,\n  `/v1/iClients`, `/v1/lookupcaches`, `/v1/tags`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to remove from the default response on\nsupported list endpoints. Unlike `include`, `exclude` does NOT trigger\nsummary projection — callers get the standard full-record shape with the\nnamed fields stripped out.\n\nRules:\n- Value regex is `{a-z A-Z . _}` (letters, dots, underscores) plus the\n  comma separator; digits are also accepted in practice. Any other\n  character returns **400 `invalid_query_params`**.\n- Empty value (`exclude=`) is ignored.\n- Certain protected identity fields **cannot be stripped** — e.g.\n  `exclude=name` on `/v1/exports` is silently ignored and `name` remains\n  in the response. Protected sets vary per resource.\n- `include` and `exclude` are **mutually exclusive**. Passing both\n  returns **400 `invalid_query_params`**: *\"Please provide either\n  include or exclude param in the request query and not both.\"*\n- Only list endpoints honor stripping — on GET-by-id the parameter is\n  silently ignored.\n- A small set of list endpoints explicitly reject both `include` and\n  `exclude` with **400 `invalid_query_params`** and a message of the form\n  *\"Include or exclude query params are not applicable for `<resource>`\n  resource.\"* Known rejections: `/v1/ediprofiles`, `/v1/environments`,\n  `/v1/iClients`, `/v1/lookupcaches`, `/v1/tags`.","schema":{"type":"string"}}},"schemas":{"Response":{"type":"object","description":"Complete integration object as returned by the API","allOf":[{"$ref":"#/components/schemas/Request"},{"$ref":"#/components/schemas/ResourceResponse"},{"$ref":"#/components/schemas/IAResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"List of connection IDs that are registered to this integration.\n\nThis is managed by the platform when users register connections through the UI or when using the\nIntegration “registerConnection” API operation. It is not set via normal integration create/update requests.","items":{"type":"string","format":"objectId"}}}}]},"Request":{"type":"object","description":"Fields that can be sent when creating or updating an integration","required":["name"],"properties":{"name":{"type":"string","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","description":"Optional description of the integration’s purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":"string","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":"Template identifier used to create/initialize this integration (commonly for Integration Apps).\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install “cards” shown during an Integration App installation.\n\nThese are primarily UI/workflow metadata. Unless you are explicitly modeling an Integration App install experience,\nomit 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","description":"Whether this card is completed."},"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":"Whether 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":"Whether 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":"Integration App lifecycle mode.\n\nUse this only when dealing with Integration App lifecycle workflows.","enum":["install","settings","uninstall"]},"settings":{"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","description":"Integration App version (or template version) associated with this integration.\n\nUsually system-managed for Integration App installs; omit unless you are explicitly controlling versions."},"tag":{"type":"string","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":"Indicates an Integration App update workflow is currently running.\n\nTypically system-managed; omit unless a workflow explicitly requires setting it."},"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":{"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":{"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 list of lifecycle steps used by the Integration App installer.\n\nThis is primarily Integration App workflow metadata. Omit unless you are working with Integration Apps.","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":"Whether the step is completed."},"type":{"type":"string","description":"Step type.\n\nChoose the type that matches the step payload:\n- `connection`: step uses `_connectionId`\n- `url`: step uses `url` or `getUrlFunction`\n- `form`: step uses `form` or `initFormFunction`\n- `template_zip`: step uses `templateZip`\n- `stack`: step uses `_stackId`\n- `edition`: step participates in license/edition changes","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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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","description":"Pending license/edition change information for the integration.\n\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","format":"objectId","description":"Target edition ID for the pending license change."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\n\nOmit 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 for flows within the integration (Integration App feature).\n\nUsed to group flows into named sections with their own settings/settingsForm.\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group.","additionalProperties":true},"settingsForm":{"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`.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"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":{"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"]},"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":"Indicates whether this integration uses Sync resources.\n\nTypically system-managed."},"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."}}}},"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\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"]},"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":{"oneOf":[{"title":"Option group","type":"object","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","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"},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible.\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"]},"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\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","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\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","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":"Core response fields shared by all Celigo resources","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource.\n\nThe _id is used in:\n- API endpoints that operate on a specific resource (e.g., GET, PUT, DELETE)\n- References from other resources (e.g., flows that use this resource)\n- Job history and error tracking\n\nFormat: 24-character hexadecimal string\n"},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was initially created.\n\nThis read-only field is automatically set during resource creation and cannot\nbe modified. It provides an audit trail for when the resource was first added\nto the system, which can be useful for:\n\n- Resource lifecycle management\n- Audit and compliance reporting\n- Troubleshooting integration timelines\n- Identifying older resources that may need review\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\n"},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was most recently updated.\n\nThis read-only field is automatically updated whenever any property of the\nresource is modified. It provides an audit trail that can be used for:\n\n- Determining if a resource has changed since it was last reviewed\n- Monitoring configuration changes during troubleshooting\n- Implementing cache invalidation strategies\n- Synchronizing related resources based on modification time\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix)\nand will always be equal to or later than the createdAt timestamp.\n"},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was marked for deletion.\n\nWhen this field is present and contains a valid timestamp, it indicates\nthat the resource has been soft-deleted (moved to the recycle bin) but not\nyet permanently removed from the system. This allows for recovery of\naccidentally deleted resources within a specified retention period.\n\nThe deletedAt timestamp enables:\n- Filtering deleted resources from active resource listings\n- Implementing time-based retention policies for permanent deletion\n- Tracking deletion events for audit and compliance purposes\n- Resource recovery workflows with clear timeframes\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\nWhen null or absent, the resource is considered active.\n"}},"required":["_id"]},"IAResourceResponse":{"type":"object","description":"Integration app response fields for resources that are part of integration apps","properties":{"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the specific integration instance that contains this resource.\n\nThis field is only populated for resources that are part of an integration app\ninstallation. It contains the unique identifier (_id) of the integration\nresource that was installed in the account.\n\nThe integration instance represents a specific installed instance of an\nintegration app, with its own configuration, settings, and runtime environment.\n\nThis reference enables:\n- Tracing the resource back to its parent integration instance\n- Permission and access control based on integration ownership\n- Lifecycle management (enabling/disabling, updating, or uninstalling)\n"},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the integration app that defines this resource.\n\nThis field is only populated for resources that are part of an integration app.\nIt contains the unique identifier (_id) of the integration app (connector)\nthat defines the structure, behavior, and templates for this resource.\n\nThe integration app is the published template that can be installed\nmultiple times across different accounts, with each installation creating\na separate integration instance (referenced by _integrationId).\n\nThis reference enables:\n- Identifying the source integration app for this resource\n- Determining which template version is being used\n- Linking to documentation, support, and marketplace information\n"}}}},"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 a list of all integrations configured in the account.","operationId":"listIntegrations","tags":["Integrations"],"parameters":[{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"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/Response"}}}}},"204":{"description":"No integrations exist in the account"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
````

## Create an integration

> Creates a new integration configuration.

````json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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"],"properties":{"name":{"type":"string","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","description":"Optional description of the integration’s purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":"string","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":"Template identifier used to create/initialize this integration (commonly for Integration Apps).\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install “cards” shown during an Integration App installation.\n\nThese are primarily UI/workflow metadata. Unless you are explicitly modeling an Integration App install experience,\nomit 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","description":"Whether this card is completed."},"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":"Whether 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":"Whether 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":"Integration App lifecycle mode.\n\nUse this only when dealing with Integration App lifecycle workflows.","enum":["install","settings","uninstall"]},"settings":{"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","description":"Integration App version (or template version) associated with this integration.\n\nUsually system-managed for Integration App installs; omit unless you are explicitly controlling versions."},"tag":{"type":"string","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":"Indicates an Integration App update workflow is currently running.\n\nTypically system-managed; omit unless a workflow explicitly requires setting it."},"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":{"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":{"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 list of lifecycle steps used by the Integration App installer.\n\nThis is primarily Integration App workflow metadata. Omit unless you are working with Integration Apps.","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":"Whether the step is completed."},"type":{"type":"string","description":"Step type.\n\nChoose the type that matches the step payload:\n- `connection`: step uses `_connectionId`\n- `url`: step uses `url` or `getUrlFunction`\n- `form`: step uses `form` or `initFormFunction`\n- `template_zip`: step uses `templateZip`\n- `stack`: step uses `_stackId`\n- `edition`: step participates in license/edition changes","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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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","description":"Pending license/edition change information for the integration.\n\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","format":"objectId","description":"Target edition ID for the pending license change."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\n\nOmit 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 for flows within the integration (Integration App feature).\n\nUsed to group flows into named sections with their own settings/settingsForm.\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group.","additionalProperties":true},"settingsForm":{"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`.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"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":{"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"]},"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":"Indicates whether this integration uses Sync resources.\n\nTypically system-managed."},"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."}}}},"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\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"]},"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":{"oneOf":[{"title":"Option group","type":"object","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","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"},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible.\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"]},"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\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","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\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","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"}}},"Response":{"type":"object","description":"Complete integration object as returned by the API","allOf":[{"$ref":"#/components/schemas/Request"},{"$ref":"#/components/schemas/ResourceResponse"},{"$ref":"#/components/schemas/IAResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"List of connection IDs that are registered to this integration.\n\nThis is managed by the platform when users register connections through the UI or when using the\nIntegration “registerConnection” API operation. It is not set via normal integration create/update requests.","items":{"type":"string","format":"objectId"}}}}]},"ResourceResponse":{"type":"object","description":"Core response fields shared by all Celigo resources","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource.\n\nThe _id is used in:\n- API endpoints that operate on a specific resource (e.g., GET, PUT, DELETE)\n- References from other resources (e.g., flows that use this resource)\n- Job history and error tracking\n\nFormat: 24-character hexadecimal string\n"},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was initially created.\n\nThis read-only field is automatically set during resource creation and cannot\nbe modified. It provides an audit trail for when the resource was first added\nto the system, which can be useful for:\n\n- Resource lifecycle management\n- Audit and compliance reporting\n- Troubleshooting integration timelines\n- Identifying older resources that may need review\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\n"},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was most recently updated.\n\nThis read-only field is automatically updated whenever any property of the\nresource is modified. It provides an audit trail that can be used for:\n\n- Determining if a resource has changed since it was last reviewed\n- Monitoring configuration changes during troubleshooting\n- Implementing cache invalidation strategies\n- Synchronizing related resources based on modification time\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix)\nand will always be equal to or later than the createdAt timestamp.\n"},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was marked for deletion.\n\nWhen this field is present and contains a valid timestamp, it indicates\nthat the resource has been soft-deleted (moved to the recycle bin) but not\nyet permanently removed from the system. This allows for recovery of\naccidentally deleted resources within a specified retention period.\n\nThe deletedAt timestamp enables:\n- Filtering deleted resources from active resource listings\n- Implementing time-based retention policies for permanent deletion\n- Tracking deletion events for audit and compliance purposes\n- Resource recovery workflows with clear timeframes\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\nWhen null or absent, the resource is considered active.\n"}},"required":["_id"]},"IAResourceResponse":{"type":"object","description":"Integration app response fields for resources that are part of integration apps","properties":{"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the specific integration instance that contains this resource.\n\nThis field is only populated for resources that are part of an integration app\ninstallation. It contains the unique identifier (_id) of the integration\nresource that was installed in the account.\n\nThe integration instance represents a specific installed instance of an\nintegration app, with its own configuration, settings, and runtime environment.\n\nThis reference enables:\n- Tracing the resource back to its parent integration instance\n- Permission and access control based on integration ownership\n- Lifecycle management (enabling/disabling, updating, or uninstalling)\n"},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the integration app that defines this resource.\n\nThis field is only populated for resources that are part of an integration app.\nIt contains the unique identifier (_id) of the integration app (connector)\nthat defines the structure, behavior, and templates for this resource.\n\nThe integration app is the published template that can be installed\nmultiple times across different accounts, with each installation creating\na separate integration instance (referenced by _integrationId).\n\nThis reference enables:\n- Identifying the source integration app for this resource\n- Determining which template version is being used\n- Linking to documentation, support, and marketplace information\n"}}},"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"]}}}},"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 configuration.","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/Response"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
````

## Get an integration

> Retrieve a single integration by its id.

````json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Response":{"type":"object","description":"Complete integration object as returned by the API","allOf":[{"$ref":"#/components/schemas/Request"},{"$ref":"#/components/schemas/ResourceResponse"},{"$ref":"#/components/schemas/IAResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"List of connection IDs that are registered to this integration.\n\nThis is managed by the platform when users register connections through the UI or when using the\nIntegration “registerConnection” API operation. It is not set via normal integration create/update requests.","items":{"type":"string","format":"objectId"}}}}]},"Request":{"type":"object","description":"Fields that can be sent when creating or updating an integration","required":["name"],"properties":{"name":{"type":"string","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","description":"Optional description of the integration’s purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":"string","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":"Template identifier used to create/initialize this integration (commonly for Integration Apps).\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install “cards” shown during an Integration App installation.\n\nThese are primarily UI/workflow metadata. Unless you are explicitly modeling an Integration App install experience,\nomit 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","description":"Whether this card is completed."},"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":"Whether 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":"Whether 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":"Integration App lifecycle mode.\n\nUse this only when dealing with Integration App lifecycle workflows.","enum":["install","settings","uninstall"]},"settings":{"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","description":"Integration App version (or template version) associated with this integration.\n\nUsually system-managed for Integration App installs; omit unless you are explicitly controlling versions."},"tag":{"type":"string","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":"Indicates an Integration App update workflow is currently running.\n\nTypically system-managed; omit unless a workflow explicitly requires setting it."},"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":{"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":{"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 list of lifecycle steps used by the Integration App installer.\n\nThis is primarily Integration App workflow metadata. Omit unless you are working with Integration Apps.","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":"Whether the step is completed."},"type":{"type":"string","description":"Step type.\n\nChoose the type that matches the step payload:\n- `connection`: step uses `_connectionId`\n- `url`: step uses `url` or `getUrlFunction`\n- `form`: step uses `form` or `initFormFunction`\n- `template_zip`: step uses `templateZip`\n- `stack`: step uses `_stackId`\n- `edition`: step participates in license/edition changes","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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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","description":"Pending license/edition change information for the integration.\n\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","format":"objectId","description":"Target edition ID for the pending license change."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\n\nOmit 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 for flows within the integration (Integration App feature).\n\nUsed to group flows into named sections with their own settings/settingsForm.\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group.","additionalProperties":true},"settingsForm":{"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`.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"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":{"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"]},"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":"Indicates whether this integration uses Sync resources.\n\nTypically system-managed."},"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."}}}},"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\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"]},"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":{"oneOf":[{"title":"Option group","type":"object","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","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"},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible.\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"]},"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\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","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\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","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":"Core response fields shared by all Celigo resources","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource.\n\nThe _id is used in:\n- API endpoints that operate on a specific resource (e.g., GET, PUT, DELETE)\n- References from other resources (e.g., flows that use this resource)\n- Job history and error tracking\n\nFormat: 24-character hexadecimal string\n"},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was initially created.\n\nThis read-only field is automatically set during resource creation and cannot\nbe modified. It provides an audit trail for when the resource was first added\nto the system, which can be useful for:\n\n- Resource lifecycle management\n- Audit and compliance reporting\n- Troubleshooting integration timelines\n- Identifying older resources that may need review\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\n"},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was most recently updated.\n\nThis read-only field is automatically updated whenever any property of the\nresource is modified. It provides an audit trail that can be used for:\n\n- Determining if a resource has changed since it was last reviewed\n- Monitoring configuration changes during troubleshooting\n- Implementing cache invalidation strategies\n- Synchronizing related resources based on modification time\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix)\nand will always be equal to or later than the createdAt timestamp.\n"},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was marked for deletion.\n\nWhen this field is present and contains a valid timestamp, it indicates\nthat the resource has been soft-deleted (moved to the recycle bin) but not\nyet permanently removed from the system. This allows for recovery of\naccidentally deleted resources within a specified retention period.\n\nThe deletedAt timestamp enables:\n- Filtering deleted resources from active resource listings\n- Implementing time-based retention policies for permanent deletion\n- Tracking deletion events for audit and compliance purposes\n- Resource recovery workflows with clear timeframes\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\nWhen null or absent, the resource is considered active.\n"}},"required":["_id"]},"IAResourceResponse":{"type":"object","description":"Integration app response fields for resources that are part of integration apps","properties":{"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the specific integration instance that contains this resource.\n\nThis field is only populated for resources that are part of an integration app\ninstallation. It contains the unique identifier (_id) of the integration\nresource that was installed in the account.\n\nThe integration instance represents a specific installed instance of an\nintegration app, with its own configuration, settings, and runtime environment.\n\nThis reference enables:\n- Tracing the resource back to its parent integration instance\n- Permission and access control based on integration ownership\n- Lifecycle management (enabling/disabling, updating, or uninstalling)\n"},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the integration app that defines this resource.\n\nThis field is only populated for resources that are part of an integration app.\nIt contains the unique identifier (_id) of the integration app (connector)\nthat defines the structure, behavior, and templates for this resource.\n\nThe integration app is the published template that can be installed\nmultiple times across different accounts, with each installation creating\na separate integration instance (referenced by _integrationId).\n\nThis reference enables:\n- Identifying the source integration app for this resource\n- Determining which template version is being used\n- Linking to documentation, support, and marketplace information\n"}}},"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":"Retrieve a single integration by its id.","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/Response"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
````

## Update an integration

> Replace an integration's mutable fields.

````json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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"],"properties":{"name":{"type":"string","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","description":"Optional description of the integration’s purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":"string","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":"Template identifier used to create/initialize this integration (commonly for Integration Apps).\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install “cards” shown during an Integration App installation.\n\nThese are primarily UI/workflow metadata. Unless you are explicitly modeling an Integration App install experience,\nomit 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","description":"Whether this card is completed."},"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":"Whether 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":"Whether 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":"Integration App lifecycle mode.\n\nUse this only when dealing with Integration App lifecycle workflows.","enum":["install","settings","uninstall"]},"settings":{"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","description":"Integration App version (or template version) associated with this integration.\n\nUsually system-managed for Integration App installs; omit unless you are explicitly controlling versions."},"tag":{"type":"string","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":"Indicates an Integration App update workflow is currently running.\n\nTypically system-managed; omit unless a workflow explicitly requires setting it."},"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":{"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":{"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 list of lifecycle steps used by the Integration App installer.\n\nThis is primarily Integration App workflow metadata. Omit unless you are working with Integration Apps.","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":"Whether the step is completed."},"type":{"type":"string","description":"Step type.\n\nChoose the type that matches the step payload:\n- `connection`: step uses `_connectionId`\n- `url`: step uses `url` or `getUrlFunction`\n- `form`: step uses `form` or `initFormFunction`\n- `template_zip`: step uses `templateZip`\n- `stack`: step uses `_stackId`\n- `edition`: step participates in license/edition changes","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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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","description":"Pending license/edition change information for the integration.\n\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","format":"objectId","description":"Target edition ID for the pending license change."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\n\nOmit 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 for flows within the integration (Integration App feature).\n\nUsed to group flows into named sections with their own settings/settingsForm.\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group.","additionalProperties":true},"settingsForm":{"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`.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"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":{"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"]},"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":"Indicates whether this integration uses Sync resources.\n\nTypically system-managed."},"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."}}}},"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\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"]},"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":{"oneOf":[{"title":"Option group","type":"object","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","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"},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible.\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"]},"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\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","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\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","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"}}},"Response":{"type":"object","description":"Complete integration object as returned by the API","allOf":[{"$ref":"#/components/schemas/Request"},{"$ref":"#/components/schemas/ResourceResponse"},{"$ref":"#/components/schemas/IAResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"List of connection IDs that are registered to this integration.\n\nThis is managed by the platform when users register connections through the UI or when using the\nIntegration “registerConnection” API operation. It is not set via normal integration create/update requests.","items":{"type":"string","format":"objectId"}}}}]},"ResourceResponse":{"type":"object","description":"Core response fields shared by all Celigo resources","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource.\n\nThe _id is used in:\n- API endpoints that operate on a specific resource (e.g., GET, PUT, DELETE)\n- References from other resources (e.g., flows that use this resource)\n- Job history and error tracking\n\nFormat: 24-character hexadecimal string\n"},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was initially created.\n\nThis read-only field is automatically set during resource creation and cannot\nbe modified. It provides an audit trail for when the resource was first added\nto the system, which can be useful for:\n\n- Resource lifecycle management\n- Audit and compliance reporting\n- Troubleshooting integration timelines\n- Identifying older resources that may need review\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\n"},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was most recently updated.\n\nThis read-only field is automatically updated whenever any property of the\nresource is modified. It provides an audit trail that can be used for:\n\n- Determining if a resource has changed since it was last reviewed\n- Monitoring configuration changes during troubleshooting\n- Implementing cache invalidation strategies\n- Synchronizing related resources based on modification time\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix)\nand will always be equal to or later than the createdAt timestamp.\n"},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was marked for deletion.\n\nWhen this field is present and contains a valid timestamp, it indicates\nthat the resource has been soft-deleted (moved to the recycle bin) but not\nyet permanently removed from the system. This allows for recovery of\naccidentally deleted resources within a specified retention period.\n\nThe deletedAt timestamp enables:\n- Filtering deleted resources from active resource listings\n- Implementing time-based retention policies for permanent deletion\n- Tracking deletion events for audit and compliance purposes\n- Resource recovery workflows with clear timeframes\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\nWhen null or absent, the resource is considered active.\n"}},"required":["_id"]},"IAResourceResponse":{"type":"object","description":"Integration app response fields for resources that are part of integration apps","properties":{"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the specific integration instance that contains this resource.\n\nThis field is only populated for resources that are part of an integration app\ninstallation. It contains the unique identifier (_id) of the integration\nresource that was installed in the account.\n\nThe integration instance represents a specific installed instance of an\nintegration app, with its own configuration, settings, and runtime environment.\n\nThis reference enables:\n- Tracing the resource back to its parent integration instance\n- Permission and access control based on integration ownership\n- Lifecycle management (enabling/disabling, updating, or uninstalling)\n"},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the integration app that defines this resource.\n\nThis field is only populated for resources that are part of an integration app.\nIt contains the unique identifier (_id) of the integration app (connector)\nthat defines the structure, behavior, and templates for this resource.\n\nThe integration app is the published template that can be installed\nmultiple times across different accounts, with each installation creating\na separate integration instance (referenced by _integrationId).\n\nThis reference enables:\n- Identifying the source integration app for this resource\n- Determining which template version is being used\n- Linking to documentation, support, and marketplace information\n"}}},"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}":{"put":{"summary":"Update an integration","operationId":"updateIntegration","tags":["Integrations"],"description":"Replace an integration's mutable fields.","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/Response"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
````

## Delete an integration

> Deletes an integration. The integration is soft-deleted and retained in the\
> recycle bin for 30 days before permanent removal. Associated flows, exports,\
> and imports are also deleted.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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}":{"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. Associated flows, exports,\nand imports are also deleted.","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"}}}}}}
```

## 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\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Only the `replace` operation is supported, and only\non whitelisted fields — all other paths are rejected with 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"],"description":"The operation to perform. Only `replace` is supported."},"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 at the given path."}}},"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`.","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.\
> Supports optionally remapping referenced connections (via connectionMap).<br>

````json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"CloneRequest":{"type":"object","description":"Request body for cloning an integration.","required":["connectionMap"],"properties":{"name":{"type":"string","description":"Name for the cloned integration. If omitted, the server generates \"Clone - <original name>\"."},"description":{"type":"string","description":"Description for the cloned integration."},"_envId":{"type":"string","format":"objectId","description":"Target environment _id. When provided, the clone is created in the\nspecified environment instead of the current one. Use\nGET /v1/environments to list available environments and their _ids.\nOmit to clone within the same 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.\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":[{"$ref":"#/components/schemas/Response"},{"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"]}}]},"Response":{"type":"object","description":"Complete integration object as returned by the API","allOf":[{"$ref":"#/components/schemas/Request"},{"$ref":"#/components/schemas/ResourceResponse"},{"$ref":"#/components/schemas/IAResourceResponse"},{"type":"object","properties":{"_registeredConnectionIds":{"type":"array","readOnly":true,"description":"List of connection IDs that are registered to this integration.\n\nThis is managed by the platform when users register connections through the UI or when using the\nIntegration “registerConnection” API operation. It is not set via normal integration create/update requests.","items":{"type":"string","format":"objectId"}}}}]},"Request":{"type":"object","description":"Fields that can be sent when creating or updating an integration","required":["name"],"properties":{"name":{"type":"string","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","description":"Optional description of the integration’s purpose and behavior.\n\nHelpful for documentation, onboarding, and clarifying what the integration does."},"readme":{"type":"string","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":"Template identifier used to create/initialize this integration (commonly for Integration Apps).\n\nOmit unless you are creating/updating an integration from a template."},"install":{"type":"array","description":"Install “cards” shown during an Integration App installation.\n\nThese are primarily UI/workflow metadata. Unless you are explicitly modeling an Integration App install experience,\nomit 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","description":"Whether this card is completed."},"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":"Whether 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":"Whether 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":"Integration App lifecycle mode.\n\nUse this only when dealing with Integration App lifecycle workflows.","enum":["install","settings","uninstall"]},"settings":{"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","description":"Integration App version (or template version) associated with this integration.\n\nUsually system-managed for Integration App installs; omit unless you are explicitly controlling versions."},"tag":{"type":"string","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":"Indicates an Integration App update workflow is currently running.\n\nTypically system-managed; omit unless a workflow explicitly requires setting it."},"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":{"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":{"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 list of lifecycle steps used by the Integration App installer.\n\nThis is primarily Integration App workflow metadata. Omit unless you are working with Integration Apps.","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":"Whether the step is completed."},"type":{"type":"string","description":"Step type.\n\nChoose the type that matches the step payload:\n- `connection`: step uses `_connectionId`\n- `url`: step uses `url` or `getUrlFunction`\n- `form`: step uses `form` or `initFormFunction`\n- `template_zip`: step uses `templateZip`\n- `stack`: step uses `_stackId`\n- `edition`: step participates in license/edition changes","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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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":"Whether the step is 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":"Whether 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":"Whether 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","description":"Pending license/edition change information for the integration.\n\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","format":"objectId","description":"Target edition ID for the pending license change."}}},"_parentId":{"type":"string","format":"objectId","description":"Parent integration ID when this integration was created as a child of another integration.\n\nOmit 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 for flows within the integration (Integration App feature).\n\nUsed to group flows into named sections with their own settings/settingsForm.\nOmit unless you are explicitly configuring flow grouping behavior.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"name":{"type":"string","description":"Display name for the flow grouping section."},"settings":{"type":"object","description":"Group-level settings for flows in this group.","additionalProperties":true},"settingsForm":{"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`.","items":{"type":"object","additionalProperties":true,"required":["name"],"properties":{"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":{"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"]},"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":"Indicates whether this integration uses Sync resources.\n\nTypically system-managed."},"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."}}}},"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\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"]},"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":{"oneOf":[{"title":"Option group","type":"object","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","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"},"description":"Array of values - if the referenced field has any of these values,\nthis field will be visible.\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"]},"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\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","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\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","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":"Core response fields shared by all Celigo resources","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource.\n\nThe _id is used in:\n- API endpoints that operate on a specific resource (e.g., GET, PUT, DELETE)\n- References from other resources (e.g., flows that use this resource)\n- Job history and error tracking\n\nFormat: 24-character hexadecimal string\n"},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was initially created.\n\nThis read-only field is automatically set during resource creation and cannot\nbe modified. It provides an audit trail for when the resource was first added\nto the system, which can be useful for:\n\n- Resource lifecycle management\n- Audit and compliance reporting\n- Troubleshooting integration timelines\n- Identifying older resources that may need review\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\n"},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was most recently updated.\n\nThis read-only field is automatically updated whenever any property of the\nresource is modified. It provides an audit trail that can be used for:\n\n- Determining if a resource has changed since it was last reviewed\n- Monitoring configuration changes during troubleshooting\n- Implementing cache invalidation strategies\n- Synchronizing related resources based on modification time\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix)\nand will always be equal to or later than the createdAt timestamp.\n"},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp indicating when the resource was marked for deletion.\n\nWhen this field is present and contains a valid timestamp, it indicates\nthat the resource has been soft-deleted (moved to the recycle bin) but not\nyet permanently removed from the system. This allows for recovery of\naccidentally deleted resources within a specified retention period.\n\nThe deletedAt timestamp enables:\n- Filtering deleted resources from active resource listings\n- Implementing time-based retention policies for permanent deletion\n- Tracking deletion events for audit and compliance purposes\n- Resource recovery workflows with clear timeframes\n\nThe timestamp is recorded in ISO 8601 format with UTC timezone (Z suffix).\nWhen null or absent, the resource is considered active.\n"}},"required":["_id"]},"IAResourceResponse":{"type":"object","description":"Integration app response fields for resources that are part of integration apps","properties":{"_integrationId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the specific integration instance that contains this resource.\n\nThis field is only populated for resources that are part of an integration app\ninstallation. It contains the unique identifier (_id) of the integration\nresource that was installed in the account.\n\nThe integration instance represents a specific installed instance of an\nintegration app, with its own configuration, settings, and runtime environment.\n\nThis reference enables:\n- Tracing the resource back to its parent integration instance\n- Permission and access control based on integration ownership\n- Lifecycle management (enabling/disabling, updating, or uninstalling)\n"},"_connectorId":{"type":"string","format":"objectId","readOnly":true,"description":"Reference to the integration app that defines this resource.\n\nThis field is only populated for resources that are part of an integration app.\nIt contains the unique identifier (_id) of the integration app (connector)\nthat defines the structure, behavior, and templates for this resource.\n\nThe integration app is the published template that can be installed\nmultiple times across different accounts, with each installation creating\na separate integration instance (referenced by _integrationId).\n\nThis reference enables:\n- Identifying the source integration app for this resource\n- Determining which template version is being used\n- Linking to documentation, support, and marketplace information\n"}}},"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":{"post":{"summary":"Clone an integration","description":"Creates a copy of an existing integration.\nSupports optionally remapping referenced connections (via connectionMap).\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":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneRequest"}}}},"responses":{"200":{"description":"Integration cloned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneResponse"}}}},"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, and lookup caches.\
> No resources are created by this endpoint.\
> \
> Returns 400 \`tools\_not\_supported\` if the integration contains tool resources, which\
> cannot be cloned.<br>

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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, and Script.\n"},"doc":{"type":"object","description":"The full resource document that would be created by the clone.","additionalProperties":true}},"required":["model","doc"]}},"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."}},"required":["objects","stackRequired","_stackId"]},"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, and lookup caches.\nNo resources are created by this endpoint.\n\nReturns 400 `tools_not_supported` if the integration contains tool resources, which\ncannot be cloned.\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":"Bad request. Returned when the integration contains tool resources that cannot be cloned.\n","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. This\
> is the data shown in the Revisions tab in the Celigo UI.\
> \
> AI guidance:\
> \- An integration with no revision history returns HTTP 204, not \`\[]\`. Treat 204 as "no revisions\
> &#x20; yet" rather than an error.\
> \- Use \`GET /v1/integrations/{\_id}/revisions/{\_revisionId}\` to retrieve full details for a single\
> &#x20; revision (though the list already includes all fields).\
> \- \`status: completed\` revisions are terminal. Only revisions in an \`inprogress\` state expose a\
> &#x20; computable diff; see \`GET .../revisions/{\_revisionId}/diff\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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 HTTP 204 with no body\nrather than `[]` — callers should treat 204 as \"no revisions yet.\"","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.\n- `snapshot` — point-in-time capture of the current integration state.\n- `pull` — changes pulled in from a related integration (another environment or clone).\n- `revert` — revert to a prior state.","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."},"_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."}},"required":["_id","_integrationId","type","status","createdAt"]},"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. This\nis the data shown in the Revisions tab in the Celigo UI.\n\nAI guidance:\n- An integration with no revision history returns HTTP 204, not `[]`. Treat 204 as \"no revisions\n  yet\" rather than an error.\n- Use `GET /v1/integrations/{_id}/revisions/{_revisionId}` to retrieve full details for a single\n  revision (though the list already includes all fields).\n- `status: completed` revisions are terminal. Only revisions in an `inprogress` state expose a\n  computable diff; see `GET .../revisions/{_revisionId}/diff`.","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.\
> \
> AI guidance:\
> \- A non-existent \`\_revisionId\` returns HTTP 404 with \`{errors:\[{field:"\_revisionId",\
> &#x20; code:"invalid\_ref"}]}\`. A non-existent \`\_id\` returns the same shape with \`field:"\_integrationId"\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n- `snapshot` — point-in-time capture of the current integration state.\n- `pull` — changes pulled in from a related integration (another environment or clone).\n- `revert` — revert to a prior state.","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."},"_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."}},"required":["_id","_integrationId","type","status","createdAt"]},"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.\n\nAI guidance:\n- A non-existent `_revisionId` returns HTTP 404 with `{errors:[{field:\"_revisionId\",\n  code:\"invalid_ref\"}]}`. A non-existent `_id` returns the same shape with `field:\"_integrationId\"`.","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.\
> \
> AI guidance:\
> \- This is the only revision type that can be created directly via the public API. \`pull\` and\
> &#x20; \`revert\` revisions are driven by ILM workflows that today require the Celigo UI (session auth).\
> \- \`description\` is required. Choose something the next person can understand in 6 months\
> &#x20; ("before deploying v2", "stable baseline after shopify migration") rather than "snapshot".\
> \- Response is the full \`Revision\` object — persist \`\_id\` and \`beforeRevisionHash\` if you plan to\
> &#x20; reference this snapshot later.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n- `snapshot` — point-in-time capture of the current integration state.\n- `pull` — changes pulled in from a related integration (another environment or clone).\n- `revert` — revert to a prior state.","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."},"_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."}},"required":["_id","_integrationId","type","status","createdAt"]},"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.\n\nAI guidance:\n- This is the only revision type that can be created directly via the public API. `pull` and\n  `revert` revisions are driven by ILM workflows that today require the Celigo UI (session auth).\n- `description` is required. Choose something the next person can understand in 6 months\n  (\"before deploying v2\", \"stable baseline after shopify migration\") rather than \"snapshot\".\n- Response is the full `Revision` object — persist `_id` and `beforeRevisionHash` if you plan to\n  reference this snapshot later.","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 — \`GET\` returns 200 for both\
> \`inprogress\` and \`completed\` pull/revert revisions. Snapshot revisions are not diffable\
> (there's no source integration to diff against), and \`canceled\` revisions drop their diff.\
> \
> AI guidance:\
> \- Snapshot revisions and \`canceled\` revisions return HTTP 400 with\
> &#x20; \`{errors:\[{code:"invalid\_revision\_state"}]}\`. Some \`inprogress\` revisions may also 400 if the\
> &#x20; install steps haven't materialized yet — retry once the revision advances.\
> \- Non-existent \`\_revisionId\` returns 404 \`invalid\_ref\`; same for non-existent \`\_id\`.\
> \- The response body is a \`{before, after}\` envelope where each side is a map keyed by resource\
> &#x20; type (e.g. \`flow\`, \`export\`, \`connection\`) whose values are maps of resourceId → full\
> &#x20; resource snapshot. Treat the inner snapshots as opaque — the shapes are the underlying\
> &#x20; resources as they existed before/after the revision, so they track the full resource models.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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 — `GET` returns 200 for both\n`inprogress` and `completed` pull/revert revisions. Snapshot revisions are not diffable\n(there's no source integration to diff against), and `canceled` revisions drop their diff.\n\nAI guidance:\n- Snapshot revisions and `canceled` revisions return HTTP 400 with\n  `{errors:[{code:\"invalid_revision_state\"}]}`. Some `inprogress` revisions may also 400 if the\n  install steps haven't materialized yet — retry once the revision advances.\n- Non-existent `_revisionId` returns 404 `invalid_ref`; same for non-existent `_id`.\n- The response body is a `{before, after}` envelope where each side is a map keyed by resource\n  type (e.g. `flow`, `export`, `connection`) whose values are maps of resourceId → full\n  resource snapshot. Treat the inner snapshots as opaque — the shapes are the underlying\n  resources as they existed before/after the revision, so they track the full resource models.","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), 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"}}}}}}
```

## 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\`.\
> \
> AI guidance:\
> \- This is the \*\*integration-wide aggregate\*\* — entries do NOT contain individual error ids. To\
> &#x20; get actionable error records (with \`errorId\` values you can retry, resolve, or assign), drill\
> &#x20; in via \`GET /v1/flows/{\_flowId}/{\_stepId}/errors\` for each flow and step.\
> \- For a per-flow (per-step) rollup, use \`GET /v1/flows/{\_flowId}/errors\`.\
> \- An integration with no flows (or no open errors) returns HTTP 204 with no body.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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."},"lastErrorAt":{"type":"string","format":"date-time","description":"Timestamp of the most recent open error on this flow. Omitted when `numError` is 0."}},"required":["_flowId","numError"]}},"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`.\n\nAI guidance:\n- This is the **integration-wide aggregate** — entries do NOT contain individual error ids. To\n  get actionable error records (with `errorId` values you can retry, resolve, or assign), drill\n  in via `GET /v1/flows/{_flowId}/{_stepId}/errors` for each flow and step.\n- For a per-flow (per-step) rollup, use `GET /v1/flows/{_flowId}/errors`.\n- An integration with no flows (or no open errors) returns HTTP 204 with no body.","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. Request shape: \`{errorIds:\[…], email}\`; response: \`{errorsToReturn:\[ids]}\`.\
> \
> AI guidance:\
> \- \*\*Use the per-step endpoint instead.\*\* \`PUT /v1/flows/{\_flowId}/{\_stepId}/errors/assign\` is\
> &#x20; what the Celigo UI actually calls — verified in HAR captures across every "assign errors"\
> &#x20; action — and it works with a plain bearer token and the \`email\` in the body, no extra\
> &#x20; headers. The integration-level endpoint below exists in the server but the UI doesn't exercise\
> &#x20; it, and it has additional auth requirements that make it impractical for most callers.\
> \- To fan out across an integration: call \`GET /v1/integrations/{\_id}/errors\` → for each flow\
> &#x20; with \`numError > 0\`, call \`GET /v1/flows/{\_flowId}/errors\` to find the steps with errors →\
> &#x20; for each such step, call \`GET /v1/flows/{\_flowId}/{\_stepId}/errors\` to collect \`errorId\`s →\
> &#x20; call \`PUT /v1/flows/{\_flowId}/{\_stepId}/errors/assign\` with \`{errorIds, email}\`. Chunk at\
> &#x20; \~1000 ids per call.\
> \- \`email\` must resolve to a user with access to the account; unknown emails return 400.\
> \- \*\*Access mechanics for this specific endpoint (documented for completeness):\*\* requires an\
> &#x20; \`integrator-ashareid\` header whose value is an ashare id where the bearer token's user is the\
> &#x20; \`sharedWithUser\`. Without it → 404 \`invalid\_ref "Integration not found"\`; malformed →\
> &#x20; 403 \`invalid\_header\_value\`; wrong-scope ashareid → 404 \`access\_restricted\`. Account-owner\
> &#x20; PATs have no ashare pointing at themselves, so can't call this endpoint directly — another\
> &#x20; reason the per-step path is the real answer.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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"}}},"required":["errorsToReturn"]},"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. Request shape: `{errorIds:[…], email}`; response: `{errorsToReturn:[ids]}`.\n\nAI guidance:\n- **Use the per-step endpoint instead.** `PUT /v1/flows/{_flowId}/{_stepId}/errors/assign` is\n  what the Celigo UI actually calls — verified in HAR captures across every \"assign errors\"\n  action — and it works with a plain bearer token and the `email` in the body, no extra\n  headers. The integration-level endpoint below exists in the server but the UI doesn't exercise\n  it, and it has additional auth requirements that make it impractical for most callers.\n- To fan out across an integration: call `GET /v1/integrations/{_id}/errors` → for each flow\n  with `numError > 0`, call `GET /v1/flows/{_flowId}/errors` to find the steps with errors →\n  for each such step, call `GET /v1/flows/{_flowId}/{_stepId}/errors` to collect `errorId`s →\n  call `PUT /v1/flows/{_flowId}/{_stepId}/errors/assign` with `{errorIds, email}`. Chunk at\n  ~1000 ids per call.\n- `email` must resolve to a user with access to the account; unknown emails return 400.\n- **Access mechanics for this specific endpoint (documented for completeness):** requires an\n  `integrator-ashareid` header whose value is an ashare id where the bearer token's user is the\n  `sharedWithUser`. Without it → 404 `invalid_ref \"Integration not found\"`; malformed →\n  403 `invalid_header_value`; wrong-scope ashareid → 404 `access_restricted`. Account-owner\n  PATs have no ashare pointing at themselves, so can't call this endpoint directly — another\n  reason the per-step path is the real answer.","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.\
> \
> AI guidance:\
> \- \*\*Account-context requirement.\*\* Like \`PUT /v1/integrations/{\_id}/errors/assign\`, this endpoint\
> &#x20; is scoped to a shared-account context — you MUST send an \`integrator-ashareid\` header whose\
> &#x20; value is an ashare id where the bearer token's user is the \`sharedWithUser\`. Discover valid\
> &#x20; ashares via \`GET /v1/ashares\` or \`GET /v1/shared/ashares\`.\
> \- \*\*Error-code decoder:\*\*\
> &#x20; \- No \`integrator-ashareid\` header → 403 \`get\_not\_allowed\` "GET resource not allowed for the\
> &#x20;   given model." (legacy error code; means the account scope is missing).\
> &#x20; \- \`integrator-ashareid\` for a share where your token's user isn't the \`sharedWithUser\` → 404\
> &#x20;   \`access\_restricted\`.\
> &#x20; \- Malformed header → 403 \`invalid\_header\_value\`.\
> \- Alternative for quick checks without the ashareid dance: the integration's own \`\_sourceId\`\
> &#x20; field points to the parent it was cloned from, and\
> &#x20; \`GET /v1/integrations?\_sourceId=\<id>\` lists the children. That's a simpler way to\
> &#x20; reason about clone relationships.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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."}},"required":["_id"],"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\nAI guidance:\n- **Account-context requirement.** Like `PUT /v1/integrations/{_id}/errors/assign`, this endpoint\n  is scoped to a shared-account context — you MUST send an `integrator-ashareid` header whose\n  value is an ashare id where the bearer token's user is the `sharedWithUser`. Discover valid\n  ashares via `GET /v1/ashares` or `GET /v1/shared/ashares`.\n- **Error-code decoder:**\n  - No `integrator-ashareid` header → 403 `get_not_allowed` \"GET resource not allowed for the\n    given model.\" (legacy error code; means the account scope is missing).\n  - `integrator-ashareid` for a share where your token's user isn't the `sharedWithUser` → 404\n    `access_restricted`.\n  - Malformed header → 403 `invalid_header_value`.\n- Alternative for quick checks without the ashareid dance: the integration's own `_sourceId`\n  field points to the parent it was cloned from, and\n  `GET /v1/integrations?_sourceId=<id>` lists the children. That's a simpler way to\n  reason about clone relationships.","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. Returns HTTP 204\
> with no body when the integration has no flows.\
> \
> AI guidance:\
> \- The response is an unwrapped array (not \`{items:\[…]}\`). Each element is a complete flow\
> &#x20; resource — the same shape as \`GET /v1/flows/{\_id}\`.\
> \- \`?limit=N\` works and caps the result count. \`?offset\`, \`?fields\`, and \`?sort\` are silently\
> &#x20; ignored by the server.\
> \- Prefer this over \`GET /v1/flows?\_integrationId=…\` when you want \*all\* flows scoped to a\
> &#x20; single integration in one call.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204\nwith no body when the integration has no flows.\n\nAI guidance:\n- The response is an unwrapped array (not `{items:[…]}`). Each element is a complete flow\n  resource — the same shape as `GET /v1/flows/{_id}`.\n- `?limit=N` works and caps the result count. `?offset`, `?fields`, and `?sort` are silently\n  ignored by the server.\n- Prefer this over `GET /v1/flows?_integrationId=…` when you want *all* flows scoped to a\n  single integration in one call.","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}}],"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. Returns HTTP 204\
> with no body when the integration has no imports.\
> \
> AI guidance:\
> \- The response is an unwrapped array (not \`{items:\[…]}\`). Each element is a complete import\
> &#x20; resource — the same shape as \`GET /v1/imports/{\_id}\`.\
> \- \*\*Known bug (off-by-one):\*\* \`?limit=N\` returns N+1 items instead of N. Account for this\
> &#x20; when paginating or capping results.\
> \- \`?offset\`, \`?fields\`, and \`?sort\` are silently ignored by the server.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204\nwith no body when the integration has no imports.\n\nAI guidance:\n- The response is an unwrapped array (not `{items:[…]}`). Each element is a complete import\n  resource — the same shape as `GET /v1/imports/{_id}`.\n- **Known bug (off-by-one):** `?limit=N` returns N+1 items instead of N. Account for this\n  when paginating or capping results.\n- `?offset`, `?fields`, and `?sort` are silently ignored by the server.","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. Returns HTTP 204\
> with no body when the integration has no exports.\
> \
> AI guidance:\
> \- The response is an unwrapped array (not \`{items:\[…]}\`). Each element is a complete export\
> &#x20; resource — the same shape as \`GET /v1/exports/{\_id}\`.\
> \- \*\*Known bug (off-by-one):\*\* \`?limit=N\` returns N+1 items instead of N — same behavior as the\
> &#x20; imports sub-resource endpoint.\
> \- \`?offset\`, \`?fields\`, and \`?sort\` are silently ignored by the server.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204\nwith no body when the integration has no exports.\n\nAI guidance:\n- The response is an unwrapped array (not `{items:[…]}`). Each element is a complete export\n  resource — the same shape as `GET /v1/exports/{_id}`.\n- **Known bug (off-by-one):** `?limit=N` returns N+1 items instead of N — same behavior as the\n  imports sub-resource endpoint.\n- `?offset`, `?fields`, and `?sort` are silently ignored by the server.","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. Returns HTTP 204 with no body when the integration has no connections.\
> \
> AI guidance:\
> \- The response is an unwrapped array (not \`{items:\[…]}\`). Each element is a complete connection\
> &#x20; resource — the same shape as \`GET /v1/connections/{\_id}\`.\
> \- \`?limit=N\` works correctly (no off-by-one bug unlike the imports/exports sub-resource\
> &#x20; endpoints).\
> \- \*\*404 on unknown integration:\*\* Unlike the flows/imports/exports sub-resource endpoints (which\
> &#x20; return 204 for a nonexistent integration), this endpoint returns 404 when the integration id\
> &#x20; does not exist.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204 with no body when the integration has no connections.\n\nAI guidance:\n- The response is an unwrapped array (not `{items:[…]}`). Each element is a complete connection\n  resource — the same shape as `GET /v1/connections/{_id}`.\n- `?limit=N` works correctly (no off-by-one bug unlike the imports/exports sub-resource\n  endpoints).\n- **404 on unknown integration:** Unlike the flows/imports/exports sub-resource endpoints (which\n  return 204 for a nonexistent integration), this endpoint returns 404 when the integration id\n  does not exist.","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. Returns HTTP 204 with no body when the integration has no async helpers.\
> \
> AI guidance:\
> \- The response is an unwrapped array (not \`{items:\[…]}\`). Each element is a complete\
> &#x20; async-helper resource — the same shape as \`GET /v1/asynchelpers/{\_id}\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204 with no body when the integration has no async helpers.\n\nAI guidance:\n- The response is an unwrapped array (not `{items:[…]}`). Each element is a complete\n  async-helper resource — the same shape as `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.\
> \
> AI guidance:\
> \- Unlike other integration sub-resource list endpoints, this always returns 200 with an array\
> &#x20; (never 204). An integration with no shares returns \`\[]\`.\
> \- Each element includes a nested \`sharedWithUser\` object containing the user's \`\_id\`, \`email\`,\
> &#x20; \`name\`, and sign-in metadata.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n\nAI guidance:\n- Unlike other integration sub-resource list endpoints, this always returns 200 with an array\n  (never 204). An integration with no shares returns `[]`.\n- Each element includes a nested `sharedWithUser` object containing the user's `_id`, `email`,\n  `name`, and sign-in metadata.","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":"Whether 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":"Whether the account requires SSO for this user."},"accountMFARequired":{"type":"boolean","description":"Whether 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. Returns HTTP 204 on success.\
> \
> AI guidance:\
> \- This is a PUT (not POST). The connection id is in the path, not the body.\
> \- To unregister the connection, use \`DELETE\` on the same path.\
> \- For registering a connection by passing the id in the request body instead, use\
> &#x20; \`PUT /v1/integrations/{\_id}/connections/register\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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 path.\nNo request body is needed. Returns HTTP 204 on success.\n\nAI guidance:\n- This is a PUT (not POST). The connection id is in the path, not the body.\n- To unregister the connection, use `DELETE` on the same path.\n- For registering a connection by passing the id in the request body instead, use\n  `PUT /v1/integrations/{_id}/connections/register`.","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. Returns HTTP 204 on success.\
> \
> AI guidance:\
> \- This is the inverse of \`PUT /v1/integrations/{\_id}/connections/{\_connectionId}/register\`.\
> \- Unregistering does not delete the connection itself — it only removes it from the\
> &#x20; integration's registered-connections list.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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":{"delete":{"operationId":"unregisterConnectionFromIntegration","tags":["Integrations"],"summary":"Unregister a connection from an integration","description":"Removes a connection's registration from the integration. Returns HTTP 204 on success.\n\nAI guidance:\n- This is the inverse of `PUT /v1/integrations/{_id}/connections/{_connectionId}/register`.\n- Unregistering does not delete the connection itself — it only removes it from the\n  integration's registered-connections list.","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."},"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. Returns HTTP 204 on success.\
> \
> AI guidance:\
> \- This is a PUT (not POST). The connection id goes in the body as \`\_connectionId\` (a single\
> &#x20; string, not an array).\
> \- For registering by path parameter instead, use\
> &#x20; \`PUT /v1/integrations/{\_id}/connections/{\_connectionId}/register\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. Returns HTTP 204 on success.\n\nAI guidance:\n- This is a PUT (not POST). The connection id goes in the body as `_connectionId` (a single\n  string, not an array).\n- For registering by path parameter instead, use\n  `PUT /v1/integrations/{_id}/connections/{_connectionId}/register`.","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"}}}}}}
```

## 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 for the integration, plus a \`childIntegrations\` array with the\
> same structure for each child.\
> \
> AI guidance:\
> \- This is primarily useful for Integration App (IA) integrations that have install/uninstall\
> &#x20; steps and child integrations.\
> \- The \`integration\` object in the response contains metadata fields like \`installSteps\`,\
> &#x20; \`flowGroupings\`, \`apiGroupings\`, \`\_registeredConnectionIds\`, \`uninstallSteps\`, and\
> &#x20; \`changeEditionSteps\`.\
> \- \`childIntegrations\` is an array (empty \`\[]\` when the integration has no children).

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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 for the integration, plus a `childIntegrations` array with the\nsame structure for each child.\n\nAI guidance:\n- This is primarily useful for Integration App (IA) integrations that have install/uninstall\n  steps and child integrations.\n- The `integration` object in the response contains metadata fields like `installSteps`,\n  `flowGroupings`, `apiGroupings`, `_registeredConnectionIds`, `uninstallSteps`, and\n  `changeEditionSteps`.\n- `childIntegrations` is an array (empty `[]` when the integration has no children).","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.\
> \
> AI guidance:\
> \- Returns 422 with code \`invalid\_ref\` and message "doesnot belongs to any Integration App."\
> &#x20; when called on a non-IA integration.\
> \- This is a PUT with no request body.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n\nAI guidance:\n- Returns 422 with code `invalid_ref` and message \"doesnot belongs to any Integration App.\"\n  when called on a non-IA integration.\n- This is a PUT with no request body.","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.\
> \
> AI guidance:\
> \- Returns 422 with code \`invalid\_integration\_app\` when the integration does not belong to an\
> &#x20; Integration App that supports edition changes.\
> \- This is a POST.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n\nAI guidance:\n- Returns 422 with code `invalid_integration_app` when the integration does not belong to an\n  Integration App that supports edition changes.\n- This is a POST.","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.\
> \
> AI guidance:\
> \- Returns 422 with code \`invalid\_ref\` and message "Script fields invalid or not found." when the\
> &#x20; Integration App does not have a valid init script.\
> \- This is a POST.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n\nAI guidance:\n- Returns 422 with code `invalid_ref` and message \"Script fields invalid or not found.\" when the\n  Integration App does not have a valid init script.\n- This is a POST.","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. This is idempotent — calling it on an integration that\
> already has no license attached is a no-op and still returns 204.\
> \
> AI guidance:\
> \- This is a PUT with no request body.\
> \- Returns 204 on success with no body.\
> \- Safe to call repeatedly — idempotent.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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. This is idempotent — calling it on an integration that\nalready has no license attached is a no-op and still returns 204.\n\nAI guidance:\n- This is a PUT with no request body.\n- Returns 204 on success with no body.\n- Safe to call repeatedly — idempotent.","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.\
> \
> AI guidance:\
> \- \*\*Account-context requirement.\*\* Like \`PUT /v1/integrations/{\_id}/errors/assign\`, this\
> &#x20; endpoint is scoped to a shared-account context — you MUST send an \`integrator-ashareid\`\
> &#x20; header whose value is an ashare id where the bearer token's user is the \`sharedWithUser\`.\
> &#x20; Discover valid ashares via \`GET /v1/ashares\` or \`GET /v1/shared/ashares\`.\
> \- \*\*Error-code decoder:\*\*\
> &#x20; \- No \`integrator-ashareid\` header → 403 \`get\_not\_allowed\`.\
> &#x20; \- \`integrator-ashareid\` for a share where your token's user isn't the \`sharedWithUser\` → 404\
> &#x20;   \`access\_restricted\`.\
> &#x20; \- Malformed header → 403 \`invalid\_header\_value\`.\
> \- The \*\*current\*\* ignore configuration lives on the integration itself, as the \`iLMIgnore\`\
> &#x20; field — read it via \`GET /v1/integrations/{\_id}\` (which works with a plain owner token). This\
> &#x20; endpoint only returns the \*menu\* of what can be ignored. To change the configuration, PATCH\
> &#x20; the integration with \`\[{op:"replace", path:"/iLMIgnore", value:{...}}]\`.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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.\n\nAI guidance:\n- **Account-context requirement.** Like `PUT /v1/integrations/{_id}/errors/assign`, this\n  endpoint is scoped to a shared-account context — you MUST send an `integrator-ashareid`\n  header whose value is an ashare id where the bearer token's user is the `sharedWithUser`.\n  Discover valid ashares via `GET /v1/ashares` or `GET /v1/shared/ashares`.\n- **Error-code decoder:**\n  - No `integrator-ashareid` header → 403 `get_not_allowed`.\n  - `integrator-ashareid` for a share where your token's user isn't the `sharedWithUser` → 404\n    `access_restricted`.\n  - Malformed header → 403 `invalid_header_value`.\n- The **current** ignore configuration lives on the integration itself, as the `iLMIgnore`\n  field — read it via `GET /v1/integrations/{_id}` (which works with a plain owner token). This\n  endpoint only returns the *menu* of what can be ignored. To change the configuration, PATCH\n  the integration with `[{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"}}}}}}}}}
```

## 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.\
> \
> AI guidance:\
> \- An empty object \`{}\` means no other resources depend on the target.\
> &#x20; This is also returned for a well-formatted but nonexistent id.

```json
{"openapi":"3.1.0","info":{"title":"Integrations","version":"1.0.0"},"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU 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."},"paths":{"type":"array","description":"JSON-path-style pointers within the dependent resource's document\nthat reference the target resource.\n","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.\n","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.\n\nAI guidance:\n- An empty object `{}` means no other resources depend on the target.\n  This is 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"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.celigo.com/api/api-reference/integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
