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

# APIs

APIs expose integration logic as HTTP endpoints that external systems can invoke.

Two modes:

* **Builder** — visual configuration with request/response mapping, routing, and transformations
* **Script** — custom JavaScript handler function for full control

Each API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`

### API schema

## The API object

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"components":{"schemas":{"API":{"required":["_id","name","createdAt","lastModified"],"description":"API resource. Shape varies by mode: builder-mode APIs carry `type`, `version`,\n`disabled`, and `builder`; script-mode APIs additionally carry `script` plus\ntop-level `_scriptId` / `function` copies. Legacy script APIs (pre-builder era)\nomit `type`, `version`, `disabled`, and `builder` entirely.","allOf":[{"$ref":"#/components/schemas/APIBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the API."},"_scriptId":{"type":"string","format":"objectId","readOnly":true,"description":"Top-level copy of `script._scriptId`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"function":{"type":"string","readOnly":true,"description":"Top-level copy of `script.function`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was last modified."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this API was created from. Present only on template-installed APIs."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when a draft API auto-deletes. Server-computed when `draft` is set at\ncreation."},"apim":{"$ref":"#/components/schemas/Apim"}}}]},"APIBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."},"_integrationId":{"type":["string","null"],"format":"objectId","description":"Integration this API belongs to. **Builder mode only** — a script-mode\nAPI is always account-level and the server silently drops this field.\nSend `null` (or omit) to keep the API account-level; on reads the field\nis omitted when unset, never `null`."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"One of the owning integration's `apiGroupings`, subdividing its APIs.\nRequires `_integrationId` in the same write — sent without it, the server\nsilently drops both — so builder mode only. `PUT /v1/apis/updateApiGrouping`\nregroups many APIs at once; this field carries the same value on a single\nAPI. On reads the field is omitted when unset, never `null`."},"description":{"type":"string","description":"Optional description of the API's purpose."},"type":{"type":"string","enum":["builder","script"],"default":"script","description":"API mode. Cannot be changed after creation. Defaults to `script` when\nomitted on create; legacy script APIs created before builder mode may\nomit it on reads as well."},"version":{"type":"string","default":"v1","pattern":"^[a-zA-Z0-9\\-_\\.]+$","description":"Version segment of the public URL (`/{version}/{relativeURI}`)."},"disabled":{"type":"boolean","default":false,"description":"When true, the API rejects all incoming requests."},"timeoutPeriod":{"type":"integer","minimum":0,"maximum":120,"description":"Request-timeout override in seconds (1–120). `0` is a sentinel meaning \"use the\n120-second default\" — the server rewrites it on write, so a stored value is never 0."},"logging":{"type":"object","description":"Execution-logging settings for the API. Builder-mode APIs are\ninitialized to `{\"mode\": \"basic\"}` at creation (when the account\nlicense has logging enabled), so the field is present on responses\nfrom the start.\n\nPOST and PUT bodies cannot set or change this field — the server\nignores it silently (the write succeeds and the stored value is\nuntouched). `PATCH /v1/apis/{_id}` with the `/logging/mode` and\n`/logging/debugUntil` paths is the only way to change it.","properties":{"mode":{"type":"string","enum":["basic","standard","detailed","accountLevel","noLogging"],"description":"Which logging level applies to requests handled by this API. Only\n`detailed` (or a temporary debug window) produces the per-step\ntrace data used by `GET /v1/apis/{_id}/requests/{executionId}`.\nPayload-capturing modes (`standard`, `detailed`) require payload\nstorage to be enabled for the account — without it, changing the\nmode fails with `422` (code `payload_storage_required`)."},"debugUntil":{"type":"string","format":"date-time","description":"While this timestamp is in the future, requests are captured in\nfull debug mode regardless of `mode`. Clears itself once the\nwindow passes. Setting it requires payload storage to be enabled\nfor the account."}}},"traceKeyTemplate":{"type":"string","maxLength":1024,"description":"Handlebars template that computes each request's trace key from the\nrequest payload, used to correlate run-history entries with source\nrecords. Absent from responses until set."},"pagination":{"type":"object","description":"Cursor pagination for builder-mode APIs whose volume-driver lookup\nsupports paging. When enabled, API responses are wrapped in a\n`{data, pagination: {has_more, next_cursor}}` envelope; consumers\nresume by sending `next_cursor` in the POST body (or the\n`Celigo-Next-Cursor` header on GET) until `has_more` is false.\nInvalid or mismatched cursors fail with `invalid_cursor_format`,\n`cursor_version_unsupported`, `cursor_signature_invalid`,\n`cursor_api_mismatch`, `cursor_filter_mismatch`, or\n`cursor_not_supported_for_api`. Absent from responses until set.","properties":{"enabled":{"type":"boolean","description":"When true, the pagination envelope and cursor contract are active for this API."}}},"script":{"$ref":"#/components/schemas/Script"},"builder":{"$ref":"#/components/schemas/Builder"},"shipworks":{"$ref":"#/components/schemas/Shipworks"},"draft":{"type":"boolean","description":"When true, this API is a draft that auto-deletes when its expiry passes\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it."}}},"Script":{"type":"object","description":"Script-mode configuration. The referenced function receives the request object\nand must return a response with `statusCode`, `headers`, and `body`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource containing the handler function."},"function":{"type":"string","description":"Name of the function to invoke within the script."}},"required":["_scriptId","function"]},"Builder":{"type":"object","description":"Builder-mode configuration defining request structure, routing, and response mapping.","properties":{"request":{"$ref":"#/components/schemas/ApiRequest"},"routers":{"type":"array","description":"Optional routers for conditional processing before the response stage.","items":{"$ref":"#/components/schemas/Router"}},"responseRouter":{"$ref":"#/components/schemas/ResponseRouter"},"responses":{"type":"array","description":"Response configurations. Must include exactly one `success` and one `fail`\nresponse; additional `custom` responses are optional.","items":{"$ref":"#/components/schemas/ApiResponse"}}}},"ApiRequest":{"type":"object","description":"Request configuration for a builder-mode API endpoint.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description."},"relativeURI":{"type":"string","maxLength":131072,"pattern":"^\\/[a-zA-Z0-9:_*\\/\\-\\.]*$","description":"URI path relative to the version. Full endpoint becomes\n`/{version}{relativeURI}`. Use colon notation for path params: `/customers/:id`."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for the API endpoint."},"headers":{"type":"array","description":"Expected request headers.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"description":{"type":"string","maxLength":10240,"description":"Description of the header's purpose"}}}},"pathParams":{"type":"array","description":"Path parameters defined in the `relativeURI`.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"description":"Parameter name (without the colon prefix)"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"queryParams":{"type":"array","description":"Expected query string parameters.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_\\-:\\/]*$","description":"Query parameter name"},"dataType":{"type":"string","enum":["string","number","boolean"],"description":"Expected data type of the parameter"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the expected request body structure. Every\nobject-typed schema node must declare at least one property for the\nAPI Builder to render it; omit this field when the endpoint has no\nbody contract.","additionalProperties":true},"mockRequest":{"type":"object","description":"Mock request data for testing the API without live calls.","properties":{"body":{"type":"object","description":"Sample request body"},"headers":{"type":"object","description":"Sample headers"},"pathParams":{"type":"object","description":"Sample path parameters"},"queryParams":{"type":"object","description":"Sample query parameters"}},"additionalProperties":false},"transform":{"type":"object","description":"Optional transformation applied to the incoming request before processing.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to a script for custom transformation logic."},"function":{"type":"string","description":"Function name in the script to execute."}}}},"required":["relativeURI","method"]},"Router":{"type":"object","description":"Conditional routing within a builder-mode API. Unlike flows, APIs only\nsupport `first_matching_branch` routing.","properties":{"id":{"type":"string","description":"Unique identifier for this router within the API."},"name":{"type":"string","description":"Display name."},"routeRecordsTo":{"type":"string","enum":["first_matching_branch"],"description":"Routing strategy. APIs only support `first_matching_branch`.","default":"first_matching_branch"},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to evaluate routing criteria.","default":"input_filters"},"script":{"type":"object","description":"Script configuration when routeRecordsUsing=\"script\".\n","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the branch name."}}},"branches":{"type":"array","description":"Processing branches, evaluated in order.","items":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"inputFilter":{"type":"object","description":"Filter criteria for branch selection.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"nextRouterId":{"type":"string","description":"Next router to chain to (or \"apiRouter\" for final routing)"},"pageProcessors":{"type":"array","description":"Processing steps to execute in this branch","items":{"type":"object","properties":{"type":{"type":"string","enum":["export","import"],"description":"Type of processor"},"_exportId":{"type":"string","format":"objectId","description":"Export resource reference (when type=\"export\")."},"_importId":{"type":"string","format":"objectId","description":"Import resource reference (when type=\"import\")."},"hooks":{"type":"object","description":"Custom scripts for processing"}}}}}}}},"required":["branches"]},"ResponseRouter":{"type":"object","description":"Final routing step that selects which response configuration to return.\nMust have `id: \"apiRouter\"`.","properties":{"id":{"type":"string","enum":["apiRouter"],"description":"Must be `\"apiRouter\"`."},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to determine which response to use."},"script":{"type":"object","description":"Script configuration when `routeRecordsUsing` is `\"script\"`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the response id."}}}}},"ApiResponse":{"type":"object","description":"Response configuration in a builder-mode API. Each API requires exactly one\n`success` and one `fail` response; additional `custom` responses are optional.","properties":{"id":{"type":"string","description":"Unique identifier for this response, referenced by the response router."},"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description of when this response is used."},"type":{"type":"string","enum":["success","fail","custom"],"description":"Response type."},"statusCode":{"type":"integer","minimum":100,"maximum":599,"description":"HTTP status code to return."},"headers":{"type":"array","description":"Response headers to include.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"value":{"type":"string","maxLength":256,"description":"Header value (can include handlebars templates)"},"description":{"type":"string","maxLength":10240,"description":"Description of the header"}}}},"inputFilter":{"type":"object","description":"Filter criteria for response selection by the response router.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the response body structure. Every object-typed\nschema node must declare at least one property for the API Builder to\nrender it; omit this field when the response body has no defined shape.","additionalProperties":true},"mockInput":{"type":["object","string"],"maxLength":0,"description":"Mock data for testing this response, in the integrator.io canonical\nrecord-page format: `{\"page_of_records\": [{\"record\": {...}}, ...]}`.\nThe server rejects any other object shape and any non-empty string\nwith a 422; the empty string `\"\"` (a UI draft artifact) is accepted\nand stored verbatim.","required":["page_of_records"],"properties":{"page_of_records":{"type":"array","description":"Pages of mock records fed to this response's mappings.","items":{"type":"object","required":["record"],"properties":{"record":{"type":"object","description":"One mock input record (freeform payload)."},"success":{"type":"boolean","description":"When true, the mock record follows the success path."},"testMode":{"type":"boolean","description":"When true, the mock record is treated as a test-mode record."}}}}},"additionalProperties":true},"mappings":{"type":"array","description":"Field mappings to transform processing results into the response body.","items":{"type":"object","required":["dataType"],"properties":{"generate":{"type":"string","description":"Target field path in the response"},"dataType":{"type":"string","enum":["string","number","boolean","object","stringarray","numberarray","booleanarray","objectarray","arrayarray"],"description":"Data type of the value this mapping writes into the response body."},"extract":{"type":"string","description":"Source field path from input data"},"hardCodedValue":{"type":"string","description":"Static value written to the target field instead of extracting\nfrom input data."}}}},"lookups":{"type":"array","description":"Static key-value lookup tables for value transformation.","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the lookup"},"map":{"type":"object","description":"Key-value mapping object"},"default":{"type":"string","description":"Default value if key not found"},"allowFailures":{"type":"boolean","description":"When true, processing continues even if this lookup fails."}}}},"hooks":{"type":"object","description":"Custom scripts to run during response processing.","properties":{"preMap":{"type":"object","description":"Script to run before applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}},"postMap":{"type":"object","description":"Script to run after applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}}}}}},"Shipworks":{"type":"object","description":"ShipWorks shipping-management credentials. Legacy feature.","properties":{"username":{"type":"string","description":"ShipWorks username."},"password":{"type":"string","description":"ShipWorks password. Masked as `\"******\"` in GET responses."}},"required":["username","password"]},"Apim":{"type":"array","readOnly":true,"description":"Publication status of this API in external API management systems.","items":{"type":"object","properties":{"apiId":{"type":"string","description":"Identifier assigned by the external API management system (a UUID, not a Celigo API _id)."},"flowId":{"type":"string","description":"Associated flow identifier in the external API management system (a UUID, not a Celigo flow _id). Empty when no flow is associated."},"status":{"type":"string","enum":["oaspending","published"],"description":"Publication status."},"definitionVersion":{"type":"string","enum":["v4"],"description":"API definition format version."}}}}}}}
```

## List APIs

> Returns all APIs configured in the account. No pagination -- every API is returned in a single\
> response. Legacy script-mode APIs (created before the builder/script distinction) may omit\
> \`type\`, \`version\`, and \`disabled\`. A 204 response means the account has zero APIs.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"After":{"name":"after","in":"query","required":false,"description":"Opaque cursor for forward pagination. Pass the value from the `Link`\nresponse header (`rel=\"next\"`) to fetch the next page.","schema":{"type":"string"}},"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"API":{"required":["_id","name","createdAt","lastModified"],"description":"API resource. Shape varies by mode: builder-mode APIs carry `type`, `version`,\n`disabled`, and `builder`; script-mode APIs additionally carry `script` plus\ntop-level `_scriptId` / `function` copies. Legacy script APIs (pre-builder era)\nomit `type`, `version`, `disabled`, and `builder` entirely.","allOf":[{"$ref":"#/components/schemas/APIBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the API."},"_scriptId":{"type":"string","format":"objectId","readOnly":true,"description":"Top-level copy of `script._scriptId`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"function":{"type":"string","readOnly":true,"description":"Top-level copy of `script.function`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was last modified."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this API was created from. Present only on template-installed APIs."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when a draft API auto-deletes. Server-computed when `draft` is set at\ncreation."},"apim":{"$ref":"#/components/schemas/Apim"}}}]},"APIBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."},"_integrationId":{"type":["string","null"],"format":"objectId","description":"Integration this API belongs to. **Builder mode only** — a script-mode\nAPI is always account-level and the server silently drops this field.\nSend `null` (or omit) to keep the API account-level; on reads the field\nis omitted when unset, never `null`."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"One of the owning integration's `apiGroupings`, subdividing its APIs.\nRequires `_integrationId` in the same write — sent without it, the server\nsilently drops both — so builder mode only. `PUT /v1/apis/updateApiGrouping`\nregroups many APIs at once; this field carries the same value on a single\nAPI. On reads the field is omitted when unset, never `null`."},"description":{"type":"string","description":"Optional description of the API's purpose."},"type":{"type":"string","enum":["builder","script"],"default":"script","description":"API mode. Cannot be changed after creation. Defaults to `script` when\nomitted on create; legacy script APIs created before builder mode may\nomit it on reads as well."},"version":{"type":"string","default":"v1","pattern":"^[a-zA-Z0-9\\-_\\.]+$","description":"Version segment of the public URL (`/{version}/{relativeURI}`)."},"disabled":{"type":"boolean","default":false,"description":"When true, the API rejects all incoming requests."},"timeoutPeriod":{"type":"integer","minimum":0,"maximum":120,"description":"Request-timeout override in seconds (1–120). `0` is a sentinel meaning \"use the\n120-second default\" — the server rewrites it on write, so a stored value is never 0."},"logging":{"type":"object","description":"Execution-logging settings for the API. Builder-mode APIs are\ninitialized to `{\"mode\": \"basic\"}` at creation (when the account\nlicense has logging enabled), so the field is present on responses\nfrom the start.\n\nPOST and PUT bodies cannot set or change this field — the server\nignores it silently (the write succeeds and the stored value is\nuntouched). `PATCH /v1/apis/{_id}` with the `/logging/mode` and\n`/logging/debugUntil` paths is the only way to change it.","properties":{"mode":{"type":"string","enum":["basic","standard","detailed","accountLevel","noLogging"],"description":"Which logging level applies to requests handled by this API. Only\n`detailed` (or a temporary debug window) produces the per-step\ntrace data used by `GET /v1/apis/{_id}/requests/{executionId}`.\nPayload-capturing modes (`standard`, `detailed`) require payload\nstorage to be enabled for the account — without it, changing the\nmode fails with `422` (code `payload_storage_required`)."},"debugUntil":{"type":"string","format":"date-time","description":"While this timestamp is in the future, requests are captured in\nfull debug mode regardless of `mode`. Clears itself once the\nwindow passes. Setting it requires payload storage to be enabled\nfor the account."}}},"traceKeyTemplate":{"type":"string","maxLength":1024,"description":"Handlebars template that computes each request's trace key from the\nrequest payload, used to correlate run-history entries with source\nrecords. Absent from responses until set."},"pagination":{"type":"object","description":"Cursor pagination for builder-mode APIs whose volume-driver lookup\nsupports paging. When enabled, API responses are wrapped in a\n`{data, pagination: {has_more, next_cursor}}` envelope; consumers\nresume by sending `next_cursor` in the POST body (or the\n`Celigo-Next-Cursor` header on GET) until `has_more` is false.\nInvalid or mismatched cursors fail with `invalid_cursor_format`,\n`cursor_version_unsupported`, `cursor_signature_invalid`,\n`cursor_api_mismatch`, `cursor_filter_mismatch`, or\n`cursor_not_supported_for_api`. Absent from responses until set.","properties":{"enabled":{"type":"boolean","description":"When true, the pagination envelope and cursor contract are active for this API."}}},"script":{"$ref":"#/components/schemas/Script"},"builder":{"$ref":"#/components/schemas/Builder"},"shipworks":{"$ref":"#/components/schemas/Shipworks"},"draft":{"type":"boolean","description":"When true, this API is a draft that auto-deletes when its expiry passes\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it."}}},"Script":{"type":"object","description":"Script-mode configuration. The referenced function receives the request object\nand must return a response with `statusCode`, `headers`, and `body`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource containing the handler function."},"function":{"type":"string","description":"Name of the function to invoke within the script."}},"required":["_scriptId","function"]},"Builder":{"type":"object","description":"Builder-mode configuration defining request structure, routing, and response mapping.","properties":{"request":{"$ref":"#/components/schemas/ApiRequest"},"routers":{"type":"array","description":"Optional routers for conditional processing before the response stage.","items":{"$ref":"#/components/schemas/Router"}},"responseRouter":{"$ref":"#/components/schemas/ResponseRouter"},"responses":{"type":"array","description":"Response configurations. Must include exactly one `success` and one `fail`\nresponse; additional `custom` responses are optional.","items":{"$ref":"#/components/schemas/ApiResponse"}}}},"ApiRequest":{"type":"object","description":"Request configuration for a builder-mode API endpoint.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description."},"relativeURI":{"type":"string","maxLength":131072,"pattern":"^\\/[a-zA-Z0-9:_*\\/\\-\\.]*$","description":"URI path relative to the version. Full endpoint becomes\n`/{version}{relativeURI}`. Use colon notation for path params: `/customers/:id`."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for the API endpoint."},"headers":{"type":"array","description":"Expected request headers.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"description":{"type":"string","maxLength":10240,"description":"Description of the header's purpose"}}}},"pathParams":{"type":"array","description":"Path parameters defined in the `relativeURI`.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"description":"Parameter name (without the colon prefix)"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"queryParams":{"type":"array","description":"Expected query string parameters.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_\\-:\\/]*$","description":"Query parameter name"},"dataType":{"type":"string","enum":["string","number","boolean"],"description":"Expected data type of the parameter"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the expected request body structure. Every\nobject-typed schema node must declare at least one property for the\nAPI Builder to render it; omit this field when the endpoint has no\nbody contract.","additionalProperties":true},"mockRequest":{"type":"object","description":"Mock request data for testing the API without live calls.","properties":{"body":{"type":"object","description":"Sample request body"},"headers":{"type":"object","description":"Sample headers"},"pathParams":{"type":"object","description":"Sample path parameters"},"queryParams":{"type":"object","description":"Sample query parameters"}},"additionalProperties":false},"transform":{"type":"object","description":"Optional transformation applied to the incoming request before processing.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to a script for custom transformation logic."},"function":{"type":"string","description":"Function name in the script to execute."}}}},"required":["relativeURI","method"]},"Router":{"type":"object","description":"Conditional routing within a builder-mode API. Unlike flows, APIs only\nsupport `first_matching_branch` routing.","properties":{"id":{"type":"string","description":"Unique identifier for this router within the API."},"name":{"type":"string","description":"Display name."},"routeRecordsTo":{"type":"string","enum":["first_matching_branch"],"description":"Routing strategy. APIs only support `first_matching_branch`.","default":"first_matching_branch"},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to evaluate routing criteria.","default":"input_filters"},"script":{"type":"object","description":"Script configuration when routeRecordsUsing=\"script\".\n","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the branch name."}}},"branches":{"type":"array","description":"Processing branches, evaluated in order.","items":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"inputFilter":{"type":"object","description":"Filter criteria for branch selection.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"nextRouterId":{"type":"string","description":"Next router to chain to (or \"apiRouter\" for final routing)"},"pageProcessors":{"type":"array","description":"Processing steps to execute in this branch","items":{"type":"object","properties":{"type":{"type":"string","enum":["export","import"],"description":"Type of processor"},"_exportId":{"type":"string","format":"objectId","description":"Export resource reference (when type=\"export\")."},"_importId":{"type":"string","format":"objectId","description":"Import resource reference (when type=\"import\")."},"hooks":{"type":"object","description":"Custom scripts for processing"}}}}}}}},"required":["branches"]},"ResponseRouter":{"type":"object","description":"Final routing step that selects which response configuration to return.\nMust have `id: \"apiRouter\"`.","properties":{"id":{"type":"string","enum":["apiRouter"],"description":"Must be `\"apiRouter\"`."},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to determine which response to use."},"script":{"type":"object","description":"Script configuration when `routeRecordsUsing` is `\"script\"`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the response id."}}}}},"ApiResponse":{"type":"object","description":"Response configuration in a builder-mode API. Each API requires exactly one\n`success` and one `fail` response; additional `custom` responses are optional.","properties":{"id":{"type":"string","description":"Unique identifier for this response, referenced by the response router."},"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description of when this response is used."},"type":{"type":"string","enum":["success","fail","custom"],"description":"Response type."},"statusCode":{"type":"integer","minimum":100,"maximum":599,"description":"HTTP status code to return."},"headers":{"type":"array","description":"Response headers to include.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"value":{"type":"string","maxLength":256,"description":"Header value (can include handlebars templates)"},"description":{"type":"string","maxLength":10240,"description":"Description of the header"}}}},"inputFilter":{"type":"object","description":"Filter criteria for response selection by the response router.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the response body structure. Every object-typed\nschema node must declare at least one property for the API Builder to\nrender it; omit this field when the response body has no defined shape.","additionalProperties":true},"mockInput":{"type":["object","string"],"maxLength":0,"description":"Mock data for testing this response, in the integrator.io canonical\nrecord-page format: `{\"page_of_records\": [{\"record\": {...}}, ...]}`.\nThe server rejects any other object shape and any non-empty string\nwith a 422; the empty string `\"\"` (a UI draft artifact) is accepted\nand stored verbatim.","required":["page_of_records"],"properties":{"page_of_records":{"type":"array","description":"Pages of mock records fed to this response's mappings.","items":{"type":"object","required":["record"],"properties":{"record":{"type":"object","description":"One mock input record (freeform payload)."},"success":{"type":"boolean","description":"When true, the mock record follows the success path."},"testMode":{"type":"boolean","description":"When true, the mock record is treated as a test-mode record."}}}}},"additionalProperties":true},"mappings":{"type":"array","description":"Field mappings to transform processing results into the response body.","items":{"type":"object","required":["dataType"],"properties":{"generate":{"type":"string","description":"Target field path in the response"},"dataType":{"type":"string","enum":["string","number","boolean","object","stringarray","numberarray","booleanarray","objectarray","arrayarray"],"description":"Data type of the value this mapping writes into the response body."},"extract":{"type":"string","description":"Source field path from input data"},"hardCodedValue":{"type":"string","description":"Static value written to the target field instead of extracting\nfrom input data."}}}},"lookups":{"type":"array","description":"Static key-value lookup tables for value transformation.","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the lookup"},"map":{"type":"object","description":"Key-value mapping object"},"default":{"type":"string","description":"Default value if key not found"},"allowFailures":{"type":"boolean","description":"When true, processing continues even if this lookup fails."}}}},"hooks":{"type":"object","description":"Custom scripts to run during response processing.","properties":{"preMap":{"type":"object","description":"Script to run before applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}},"postMap":{"type":"object","description":"Script to run after applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}}}}}},"Shipworks":{"type":"object","description":"ShipWorks shipping-management credentials. Legacy feature.","properties":{"username":{"type":"string","description":"ShipWorks username."},"password":{"type":"string","description":"ShipWorks password. Masked as `\"******\"` in GET responses."}},"required":["username","password"]},"Apim":{"type":"array","readOnly":true,"description":"Publication status of this API in external API management systems.","items":{"type":"object","properties":{"apiId":{"type":"string","description":"Identifier assigned by the external API management system (a UUID, not a Celigo API _id)."},"flowId":{"type":"string","description":"Associated flow identifier in the external API management system (a UUID, not a Celigo flow _id). Empty when no flow is associated."},"status":{"type":"string","enum":["oaspending","published"],"description":"Publication status."},"definitionVersion":{"type":"string","enum":["v4"],"description":"API definition format version."}}}}},"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/apis":{"get":{"summary":"List APIs","description":"Returns all APIs configured in the account. No pagination -- every API is returned in a single\nresponse. Legacy script-mode APIs (created before the builder/script distinction) may omit\n`type`, `version`, and `disabled`. A 204 response means the account has zero APIs.","operationId":"listApis","tags":["APIs"],"parameters":[{"name":"limit","in":"query","description":"Maximum number of records to return per page.","schema":{"type":"integer","minimum":1}},{"name":"name","in":"query","description":"Filter by name — a substring match, not an exact match. An empty\nvalue is ignored.","schema":{"type":"string"}},{"name":"disabled","in":"query","description":"Filter by the `disabled` flag.","schema":{"type":"boolean"}},{"$ref":"#/components/parameters/After"},{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Successfully retrieved list of APIs.","headers":{"Link":{"description":"RFC-5988 pagination links. When more pages remain, includes a `<...>; rel=\"next\"` entry;\nabsent on the final page.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/API"}}}}},"204":{"description":"No APIs exist in the account."},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Create an API

> Creates a new API. For \`script\` mode, include \`script.\_scriptId\` and \`script.function\` (the\
> server also copies these to the top level in the response). For \`builder\` mode,\
> \`builder.request\` is required (at minimum \`relativeURI\` and \`method\`).\
> \
> Builder-mode APIs are created with \`logging: {"mode": "basic"}\` when the account license\
> has logging enabled -- the request body cannot override this (\`logging\` is ignored on POST\
> and PUT; change it afterwards with \`PATCH /v1/apis/{\_id}\`).

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Request body for creating or updating an API.\n\nFor builder-mode APIs, populate the `builder` object (at minimum\n`builder.request.relativeURI` and `builder.request.method`); the `script`\nfield is ignored. For script-mode APIs, populate `script` with `_scriptId`\nand `function`; the `builder` field is ignored. On PUT, send the complete\nobject — omitted fields revert to defaults.\n\nSet `type` explicitly to `builder` or `script`. The server infers `script`\nwhen `type` is omitted, but new APIs must declare it.","required":["name","type"],"allOf":[{"$ref":"#/components/schemas/APIBase"}]},"APIBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."},"_integrationId":{"type":["string","null"],"format":"objectId","description":"Integration this API belongs to. **Builder mode only** — a script-mode\nAPI is always account-level and the server silently drops this field.\nSend `null` (or omit) to keep the API account-level; on reads the field\nis omitted when unset, never `null`."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"One of the owning integration's `apiGroupings`, subdividing its APIs.\nRequires `_integrationId` in the same write — sent without it, the server\nsilently drops both — so builder mode only. `PUT /v1/apis/updateApiGrouping`\nregroups many APIs at once; this field carries the same value on a single\nAPI. On reads the field is omitted when unset, never `null`."},"description":{"type":"string","description":"Optional description of the API's purpose."},"type":{"type":"string","enum":["builder","script"],"default":"script","description":"API mode. Cannot be changed after creation. Defaults to `script` when\nomitted on create; legacy script APIs created before builder mode may\nomit it on reads as well."},"version":{"type":"string","default":"v1","pattern":"^[a-zA-Z0-9\\-_\\.]+$","description":"Version segment of the public URL (`/{version}/{relativeURI}`)."},"disabled":{"type":"boolean","default":false,"description":"When true, the API rejects all incoming requests."},"timeoutPeriod":{"type":"integer","minimum":0,"maximum":120,"description":"Request-timeout override in seconds (1–120). `0` is a sentinel meaning \"use the\n120-second default\" — the server rewrites it on write, so a stored value is never 0."},"logging":{"type":"object","description":"Execution-logging settings for the API. Builder-mode APIs are\ninitialized to `{\"mode\": \"basic\"}` at creation (when the account\nlicense has logging enabled), so the field is present on responses\nfrom the start.\n\nPOST and PUT bodies cannot set or change this field — the server\nignores it silently (the write succeeds and the stored value is\nuntouched). `PATCH /v1/apis/{_id}` with the `/logging/mode` and\n`/logging/debugUntil` paths is the only way to change it.","properties":{"mode":{"type":"string","enum":["basic","standard","detailed","accountLevel","noLogging"],"description":"Which logging level applies to requests handled by this API. Only\n`detailed` (or a temporary debug window) produces the per-step\ntrace data used by `GET /v1/apis/{_id}/requests/{executionId}`.\nPayload-capturing modes (`standard`, `detailed`) require payload\nstorage to be enabled for the account — without it, changing the\nmode fails with `422` (code `payload_storage_required`)."},"debugUntil":{"type":"string","format":"date-time","description":"While this timestamp is in the future, requests are captured in\nfull debug mode regardless of `mode`. Clears itself once the\nwindow passes. Setting it requires payload storage to be enabled\nfor the account."}}},"traceKeyTemplate":{"type":"string","maxLength":1024,"description":"Handlebars template that computes each request's trace key from the\nrequest payload, used to correlate run-history entries with source\nrecords. Absent from responses until set."},"pagination":{"type":"object","description":"Cursor pagination for builder-mode APIs whose volume-driver lookup\nsupports paging. When enabled, API responses are wrapped in a\n`{data, pagination: {has_more, next_cursor}}` envelope; consumers\nresume by sending `next_cursor` in the POST body (or the\n`Celigo-Next-Cursor` header on GET) until `has_more` is false.\nInvalid or mismatched cursors fail with `invalid_cursor_format`,\n`cursor_version_unsupported`, `cursor_signature_invalid`,\n`cursor_api_mismatch`, `cursor_filter_mismatch`, or\n`cursor_not_supported_for_api`. Absent from responses until set.","properties":{"enabled":{"type":"boolean","description":"When true, the pagination envelope and cursor contract are active for this API."}}},"script":{"$ref":"#/components/schemas/Script"},"builder":{"$ref":"#/components/schemas/Builder"},"shipworks":{"$ref":"#/components/schemas/Shipworks"},"draft":{"type":"boolean","description":"When true, this API is a draft that auto-deletes when its expiry passes\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it."}}},"Script":{"type":"object","description":"Script-mode configuration. The referenced function receives the request object\nand must return a response with `statusCode`, `headers`, and `body`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource containing the handler function."},"function":{"type":"string","description":"Name of the function to invoke within the script."}},"required":["_scriptId","function"]},"Builder":{"type":"object","description":"Builder-mode configuration defining request structure, routing, and response mapping.","properties":{"request":{"$ref":"#/components/schemas/ApiRequest"},"routers":{"type":"array","description":"Optional routers for conditional processing before the response stage.","items":{"$ref":"#/components/schemas/Router"}},"responseRouter":{"$ref":"#/components/schemas/ResponseRouter"},"responses":{"type":"array","description":"Response configurations. Must include exactly one `success` and one `fail`\nresponse; additional `custom` responses are optional.","items":{"$ref":"#/components/schemas/ApiResponse"}}}},"ApiRequest":{"type":"object","description":"Request configuration for a builder-mode API endpoint.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description."},"relativeURI":{"type":"string","maxLength":131072,"pattern":"^\\/[a-zA-Z0-9:_*\\/\\-\\.]*$","description":"URI path relative to the version. Full endpoint becomes\n`/{version}{relativeURI}`. Use colon notation for path params: `/customers/:id`."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for the API endpoint."},"headers":{"type":"array","description":"Expected request headers.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"description":{"type":"string","maxLength":10240,"description":"Description of the header's purpose"}}}},"pathParams":{"type":"array","description":"Path parameters defined in the `relativeURI`.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"description":"Parameter name (without the colon prefix)"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"queryParams":{"type":"array","description":"Expected query string parameters.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_\\-:\\/]*$","description":"Query parameter name"},"dataType":{"type":"string","enum":["string","number","boolean"],"description":"Expected data type of the parameter"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the expected request body structure. Every\nobject-typed schema node must declare at least one property for the\nAPI Builder to render it; omit this field when the endpoint has no\nbody contract.","additionalProperties":true},"mockRequest":{"type":"object","description":"Mock request data for testing the API without live calls.","properties":{"body":{"type":"object","description":"Sample request body"},"headers":{"type":"object","description":"Sample headers"},"pathParams":{"type":"object","description":"Sample path parameters"},"queryParams":{"type":"object","description":"Sample query parameters"}},"additionalProperties":false},"transform":{"type":"object","description":"Optional transformation applied to the incoming request before processing.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to a script for custom transformation logic."},"function":{"type":"string","description":"Function name in the script to execute."}}}},"required":["relativeURI","method"]},"Router":{"type":"object","description":"Conditional routing within a builder-mode API. Unlike flows, APIs only\nsupport `first_matching_branch` routing.","properties":{"id":{"type":"string","description":"Unique identifier for this router within the API."},"name":{"type":"string","description":"Display name."},"routeRecordsTo":{"type":"string","enum":["first_matching_branch"],"description":"Routing strategy. APIs only support `first_matching_branch`.","default":"first_matching_branch"},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to evaluate routing criteria.","default":"input_filters"},"script":{"type":"object","description":"Script configuration when routeRecordsUsing=\"script\".\n","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the branch name."}}},"branches":{"type":"array","description":"Processing branches, evaluated in order.","items":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"inputFilter":{"type":"object","description":"Filter criteria for branch selection.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"nextRouterId":{"type":"string","description":"Next router to chain to (or \"apiRouter\" for final routing)"},"pageProcessors":{"type":"array","description":"Processing steps to execute in this branch","items":{"type":"object","properties":{"type":{"type":"string","enum":["export","import"],"description":"Type of processor"},"_exportId":{"type":"string","format":"objectId","description":"Export resource reference (when type=\"export\")."},"_importId":{"type":"string","format":"objectId","description":"Import resource reference (when type=\"import\")."},"hooks":{"type":"object","description":"Custom scripts for processing"}}}}}}}},"required":["branches"]},"ResponseRouter":{"type":"object","description":"Final routing step that selects which response configuration to return.\nMust have `id: \"apiRouter\"`.","properties":{"id":{"type":"string","enum":["apiRouter"],"description":"Must be `\"apiRouter\"`."},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to determine which response to use."},"script":{"type":"object","description":"Script configuration when `routeRecordsUsing` is `\"script\"`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the response id."}}}}},"ApiResponse":{"type":"object","description":"Response configuration in a builder-mode API. Each API requires exactly one\n`success` and one `fail` response; additional `custom` responses are optional.","properties":{"id":{"type":"string","description":"Unique identifier for this response, referenced by the response router."},"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description of when this response is used."},"type":{"type":"string","enum":["success","fail","custom"],"description":"Response type."},"statusCode":{"type":"integer","minimum":100,"maximum":599,"description":"HTTP status code to return."},"headers":{"type":"array","description":"Response headers to include.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"value":{"type":"string","maxLength":256,"description":"Header value (can include handlebars templates)"},"description":{"type":"string","maxLength":10240,"description":"Description of the header"}}}},"inputFilter":{"type":"object","description":"Filter criteria for response selection by the response router.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the response body structure. Every object-typed\nschema node must declare at least one property for the API Builder to\nrender it; omit this field when the response body has no defined shape.","additionalProperties":true},"mockInput":{"type":["object","string"],"maxLength":0,"description":"Mock data for testing this response, in the integrator.io canonical\nrecord-page format: `{\"page_of_records\": [{\"record\": {...}}, ...]}`.\nThe server rejects any other object shape and any non-empty string\nwith a 422; the empty string `\"\"` (a UI draft artifact) is accepted\nand stored verbatim.","required":["page_of_records"],"properties":{"page_of_records":{"type":"array","description":"Pages of mock records fed to this response's mappings.","items":{"type":"object","required":["record"],"properties":{"record":{"type":"object","description":"One mock input record (freeform payload)."},"success":{"type":"boolean","description":"When true, the mock record follows the success path."},"testMode":{"type":"boolean","description":"When true, the mock record is treated as a test-mode record."}}}}},"additionalProperties":true},"mappings":{"type":"array","description":"Field mappings to transform processing results into the response body.","items":{"type":"object","required":["dataType"],"properties":{"generate":{"type":"string","description":"Target field path in the response"},"dataType":{"type":"string","enum":["string","number","boolean","object","stringarray","numberarray","booleanarray","objectarray","arrayarray"],"description":"Data type of the value this mapping writes into the response body."},"extract":{"type":"string","description":"Source field path from input data"},"hardCodedValue":{"type":"string","description":"Static value written to the target field instead of extracting\nfrom input data."}}}},"lookups":{"type":"array","description":"Static key-value lookup tables for value transformation.","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the lookup"},"map":{"type":"object","description":"Key-value mapping object"},"default":{"type":"string","description":"Default value if key not found"},"allowFailures":{"type":"boolean","description":"When true, processing continues even if this lookup fails."}}}},"hooks":{"type":"object","description":"Custom scripts to run during response processing.","properties":{"preMap":{"type":"object","description":"Script to run before applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}},"postMap":{"type":"object","description":"Script to run after applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}}}}}},"Shipworks":{"type":"object","description":"ShipWorks shipping-management credentials. Legacy feature.","properties":{"username":{"type":"string","description":"ShipWorks username."},"password":{"type":"string","description":"ShipWorks password. Masked as `\"******\"` in GET responses."}},"required":["username","password"]},"API":{"required":["_id","name","createdAt","lastModified"],"description":"API resource. Shape varies by mode: builder-mode APIs carry `type`, `version`,\n`disabled`, and `builder`; script-mode APIs additionally carry `script` plus\ntop-level `_scriptId` / `function` copies. Legacy script APIs (pre-builder era)\nomit `type`, `version`, `disabled`, and `builder` entirely.","allOf":[{"$ref":"#/components/schemas/APIBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the API."},"_scriptId":{"type":"string","format":"objectId","readOnly":true,"description":"Top-level copy of `script._scriptId`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"function":{"type":"string","readOnly":true,"description":"Top-level copy of `script.function`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was last modified."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this API was created from. Present only on template-installed APIs."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when a draft API auto-deletes. Server-computed when `draft` is set at\ncreation."},"apim":{"$ref":"#/components/schemas/Apim"}}}]},"Apim":{"type":"array","readOnly":true,"description":"Publication status of this API in external API management systems.","items":{"type":"object","properties":{"apiId":{"type":"string","description":"Identifier assigned by the external API management system (a UUID, not a Celigo API _id)."},"flowId":{"type":"string","description":"Associated flow identifier in the external API management system (a UUID, not a Celigo flow _id). Empty when no flow is associated."},"status":{"type":"string","enum":["oaspending","published"],"description":"Publication status."},"definitionVersion":{"type":"string","enum":["v4"],"description":"API definition format version."}}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/apis":{"post":{"summary":"Create an API","description":"Creates a new API. For `script` mode, include `script._scriptId` and `script.function` (the\nserver also copies these to the top level in the response). For `builder` mode,\n`builder.request` is required (at minimum `relativeURI` and `method`).\n\nBuilder-mode APIs are created with `logging: {\"mode\": \"basic\"}` when the account license\nhas logging enabled -- the request body cannot override this (`logging` is ignored on POST\nand PUT; change it afterwards with `PATCH /v1/apis/{_id}`).","operationId":"createApi","tags":["APIs"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"201":{"description":"API created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/API"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## List month-to-date API invocation counts

> Returns one invocation-counter record per resource + method + relativeURI in the current month.\
> Counts API-style invocations across every resource type that exposes an HTTP-callable endpoint:\
> custom APIs (builder and script), individual exports/imports called via \`/invoke\`, virtual\
> imports, and APIM-fronted invocations.\
> \
> The endpoint aggregates -- it does not return one record per individual call. Each entry rolls\
> up every invocation of that (resource, method, URI) triple in the current month. Counters reset\
> on the 1st of each month; there is no pagination and no historical-months filter on this path.\
> \
> \`ioInvocationCount\` bills against the Celigo subscription; \`apimInvocationCount\` is billed\
> separately for external APIM passthrough. To find the resource behind a row, read\
> \`metadata.\_resourceId\` (present for exports/imports) or parse the resource id out of\
> \`relativeURI\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"Include":{"name":"include","in":"query","required":false,"description":"Comma-separated list of fields to project into each returned record.\nTriggers summary projection: the response contains a minimal identity\nset (`_id`, `name`, plus resource-specific fields) with the requested\nfields added on top. Supports dot notation for nested fields.\nMutually exclusive with `exclude`.","schema":{"type":"string"}},"Exclude":{"name":"exclude","in":"query","required":false,"description":"Comma-separated list of fields to strip from the default response.\nUnlike `include`, does not trigger summary projection — returns the\nfull record with the named fields removed. Protected identity fields\n(e.g. `name`) cannot be stripped. Mutually exclusive with `include`.","schema":{"type":"string"}}},"schemas":{"ApisUsageResponse":{"type":"object","description":"Month-to-date invocation counters for every API endpoint that has been called in the account.\nReturned by `GET /v1/apis/usage`. Each entry in `usages[]` represents one resource + method +\nrelativeURI triple — the same export or import invoked via two different methods yields two\nentries. Counters are cumulative for the month named in `month` / `year` and reset on the 1st.","properties":{"usages":{"type":"array","description":"Per-endpoint invocation records. Empty array when the account hasn't invoked any API endpoints\nthis month. Includes entries for every resource that can be invoked as an API —\ncustom APIs, individual exports/imports (`/v1/exports/{id}/invoke`, `/v1/imports/{id}/invoke`),\nvirtual imports, and script APIs.","items":{"$ref":"#/components/schemas/ApisUsageEntry"}},"externalApimCount":{"type":"integer","description":"Account-wide count of invocations that arrived through an external API Management layer\n(APIM) in front of integrator.io for the current month. Aggregate counterpart to the\nper-endpoint `apimInvocationCount` values in `usages[]`. Absent on some responses when the\naccount has never been routed through an external APIM."}}},"ApisUsageEntry":{"type":"object","description":"One month's invocation record for a single API-callable endpoint. Keyed by the\nresource + HTTP method + relativeURI combination — the same export invoked via two HTTP methods\nproduces two separate entries.","properties":{"_id":{"type":"string","format":"objectId","description":"Unique id of this usage record (not the resource id — see `metadata._resourceId`)."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method the endpoint was called with."},"relativeURI":{"type":"string","description":"The endpoint path (relative to `https://api.integrator.io`) that was invoked. Common shapes:\n`/v1/exports/{_exportId}/invoke`, `/v1/imports/{_importId}/invoke`,\n`/v1/connections/{_connectionId}/import` for virtual imports,\n`/v1/apis/{_apiId}/request` for script-mode APIs, and\n`/apis/v1/<relativeURI>` for builder-mode APIs."},"metadata":{"type":"object","description":"Human-readable labeling of the resource behind this usage record.","properties":{"_resourceId":{"type":"string","format":"objectId","description":"Id of the underlying export, import, or API resource. Omitted for some resource types\n(e.g. connection-scoped virtual imports) where the URL itself fully identifies the target."},"name":{"type":"string","description":"Display name of the resource at the time of invocation."},"type":{"type":"string","enum":["export","import","virtualImport","script","apiBuilder"],"description":"Resource flavor. `virtualImport` is a connection-scoped import (connector-embedded).\n`script` is a script-mode API. `apiBuilder` is a builder-mode API."}}},"month":{"type":"integer","minimum":1,"maximum":12,"description":"Calendar month (1 = January) the counters cover."},"year":{"type":"integer","description":"Four-digit year the counters cover."},"ioInvocationCount":{"type":"integer","description":"Number of times the endpoint was invoked through integrator.io's own API front door. This is\nthe counter that bills against the subscription's API invocation entitlement."},"apimInvocationCount":{"type":"integer","description":"Number of times the endpoint was invoked through an external API Management layer (APIM) in\nfront of integrator.io. Billed separately from `ioInvocationCount`."},"createdAt":{"type":"string","format":"date-time","description":"When this monthly counter record was first created (the first invocation of the month)."}}}},"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/apis/usage":{"get":{"operationId":"listApisUsage","tags":["APIs"],"summary":"List month-to-date API invocation counts","description":"Returns one invocation-counter record per resource + method + relativeURI in the current month.\nCounts API-style invocations across every resource type that exposes an HTTP-callable endpoint:\ncustom APIs (builder and script), individual exports/imports called via `/invoke`, virtual\nimports, and APIM-fronted invocations.\n\nThe endpoint aggregates -- it does not return one record per individual call. Each entry rolls\nup every invocation of that (resource, method, URI) triple in the current month. Counters reset\non the 1st of each month; there is no pagination and no historical-months filter on this path.\n\n`ioInvocationCount` bills against the Celigo subscription; `apimInvocationCount` is billed\nseparately for external APIM passthrough. To find the resource behind a row, read\n`metadata._resourceId` (present for exports/imports) or parse the resource id out of\n`relativeURI`.","parameters":[{"$ref":"#/components/parameters/Include"},{"$ref":"#/components/parameters/Exclude"}],"responses":{"200":{"description":"Usage breakdown for the current month. `usages[]` is empty when no endpoints have been invoked yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApisUsageResponse"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Get an API

> Returns the complete configuration of a specific API.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"API":{"required":["_id","name","createdAt","lastModified"],"description":"API resource. Shape varies by mode: builder-mode APIs carry `type`, `version`,\n`disabled`, and `builder`; script-mode APIs additionally carry `script` plus\ntop-level `_scriptId` / `function` copies. Legacy script APIs (pre-builder era)\nomit `type`, `version`, `disabled`, and `builder` entirely.","allOf":[{"$ref":"#/components/schemas/APIBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the API."},"_scriptId":{"type":"string","format":"objectId","readOnly":true,"description":"Top-level copy of `script._scriptId`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"function":{"type":"string","readOnly":true,"description":"Top-level copy of `script.function`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was last modified."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this API was created from. Present only on template-installed APIs."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when a draft API auto-deletes. Server-computed when `draft` is set at\ncreation."},"apim":{"$ref":"#/components/schemas/Apim"}}}]},"APIBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."},"_integrationId":{"type":["string","null"],"format":"objectId","description":"Integration this API belongs to. **Builder mode only** — a script-mode\nAPI is always account-level and the server silently drops this field.\nSend `null` (or omit) to keep the API account-level; on reads the field\nis omitted when unset, never `null`."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"One of the owning integration's `apiGroupings`, subdividing its APIs.\nRequires `_integrationId` in the same write — sent without it, the server\nsilently drops both — so builder mode only. `PUT /v1/apis/updateApiGrouping`\nregroups many APIs at once; this field carries the same value on a single\nAPI. On reads the field is omitted when unset, never `null`."},"description":{"type":"string","description":"Optional description of the API's purpose."},"type":{"type":"string","enum":["builder","script"],"default":"script","description":"API mode. Cannot be changed after creation. Defaults to `script` when\nomitted on create; legacy script APIs created before builder mode may\nomit it on reads as well."},"version":{"type":"string","default":"v1","pattern":"^[a-zA-Z0-9\\-_\\.]+$","description":"Version segment of the public URL (`/{version}/{relativeURI}`)."},"disabled":{"type":"boolean","default":false,"description":"When true, the API rejects all incoming requests."},"timeoutPeriod":{"type":"integer","minimum":0,"maximum":120,"description":"Request-timeout override in seconds (1–120). `0` is a sentinel meaning \"use the\n120-second default\" — the server rewrites it on write, so a stored value is never 0."},"logging":{"type":"object","description":"Execution-logging settings for the API. Builder-mode APIs are\ninitialized to `{\"mode\": \"basic\"}` at creation (when the account\nlicense has logging enabled), so the field is present on responses\nfrom the start.\n\nPOST and PUT bodies cannot set or change this field — the server\nignores it silently (the write succeeds and the stored value is\nuntouched). `PATCH /v1/apis/{_id}` with the `/logging/mode` and\n`/logging/debugUntil` paths is the only way to change it.","properties":{"mode":{"type":"string","enum":["basic","standard","detailed","accountLevel","noLogging"],"description":"Which logging level applies to requests handled by this API. Only\n`detailed` (or a temporary debug window) produces the per-step\ntrace data used by `GET /v1/apis/{_id}/requests/{executionId}`.\nPayload-capturing modes (`standard`, `detailed`) require payload\nstorage to be enabled for the account — without it, changing the\nmode fails with `422` (code `payload_storage_required`)."},"debugUntil":{"type":"string","format":"date-time","description":"While this timestamp is in the future, requests are captured in\nfull debug mode regardless of `mode`. Clears itself once the\nwindow passes. Setting it requires payload storage to be enabled\nfor the account."}}},"traceKeyTemplate":{"type":"string","maxLength":1024,"description":"Handlebars template that computes each request's trace key from the\nrequest payload, used to correlate run-history entries with source\nrecords. Absent from responses until set."},"pagination":{"type":"object","description":"Cursor pagination for builder-mode APIs whose volume-driver lookup\nsupports paging. When enabled, API responses are wrapped in a\n`{data, pagination: {has_more, next_cursor}}` envelope; consumers\nresume by sending `next_cursor` in the POST body (or the\n`Celigo-Next-Cursor` header on GET) until `has_more` is false.\nInvalid or mismatched cursors fail with `invalid_cursor_format`,\n`cursor_version_unsupported`, `cursor_signature_invalid`,\n`cursor_api_mismatch`, `cursor_filter_mismatch`, or\n`cursor_not_supported_for_api`. Absent from responses until set.","properties":{"enabled":{"type":"boolean","description":"When true, the pagination envelope and cursor contract are active for this API."}}},"script":{"$ref":"#/components/schemas/Script"},"builder":{"$ref":"#/components/schemas/Builder"},"shipworks":{"$ref":"#/components/schemas/Shipworks"},"draft":{"type":"boolean","description":"When true, this API is a draft that auto-deletes when its expiry passes\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it."}}},"Script":{"type":"object","description":"Script-mode configuration. The referenced function receives the request object\nand must return a response with `statusCode`, `headers`, and `body`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource containing the handler function."},"function":{"type":"string","description":"Name of the function to invoke within the script."}},"required":["_scriptId","function"]},"Builder":{"type":"object","description":"Builder-mode configuration defining request structure, routing, and response mapping.","properties":{"request":{"$ref":"#/components/schemas/ApiRequest"},"routers":{"type":"array","description":"Optional routers for conditional processing before the response stage.","items":{"$ref":"#/components/schemas/Router"}},"responseRouter":{"$ref":"#/components/schemas/ResponseRouter"},"responses":{"type":"array","description":"Response configurations. Must include exactly one `success` and one `fail`\nresponse; additional `custom` responses are optional.","items":{"$ref":"#/components/schemas/ApiResponse"}}}},"ApiRequest":{"type":"object","description":"Request configuration for a builder-mode API endpoint.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description."},"relativeURI":{"type":"string","maxLength":131072,"pattern":"^\\/[a-zA-Z0-9:_*\\/\\-\\.]*$","description":"URI path relative to the version. Full endpoint becomes\n`/{version}{relativeURI}`. Use colon notation for path params: `/customers/:id`."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for the API endpoint."},"headers":{"type":"array","description":"Expected request headers.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"description":{"type":"string","maxLength":10240,"description":"Description of the header's purpose"}}}},"pathParams":{"type":"array","description":"Path parameters defined in the `relativeURI`.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"description":"Parameter name (without the colon prefix)"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"queryParams":{"type":"array","description":"Expected query string parameters.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_\\-:\\/]*$","description":"Query parameter name"},"dataType":{"type":"string","enum":["string","number","boolean"],"description":"Expected data type of the parameter"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the expected request body structure. Every\nobject-typed schema node must declare at least one property for the\nAPI Builder to render it; omit this field when the endpoint has no\nbody contract.","additionalProperties":true},"mockRequest":{"type":"object","description":"Mock request data for testing the API without live calls.","properties":{"body":{"type":"object","description":"Sample request body"},"headers":{"type":"object","description":"Sample headers"},"pathParams":{"type":"object","description":"Sample path parameters"},"queryParams":{"type":"object","description":"Sample query parameters"}},"additionalProperties":false},"transform":{"type":"object","description":"Optional transformation applied to the incoming request before processing.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to a script for custom transformation logic."},"function":{"type":"string","description":"Function name in the script to execute."}}}},"required":["relativeURI","method"]},"Router":{"type":"object","description":"Conditional routing within a builder-mode API. Unlike flows, APIs only\nsupport `first_matching_branch` routing.","properties":{"id":{"type":"string","description":"Unique identifier for this router within the API."},"name":{"type":"string","description":"Display name."},"routeRecordsTo":{"type":"string","enum":["first_matching_branch"],"description":"Routing strategy. APIs only support `first_matching_branch`.","default":"first_matching_branch"},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to evaluate routing criteria.","default":"input_filters"},"script":{"type":"object","description":"Script configuration when routeRecordsUsing=\"script\".\n","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the branch name."}}},"branches":{"type":"array","description":"Processing branches, evaluated in order.","items":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"inputFilter":{"type":"object","description":"Filter criteria for branch selection.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"nextRouterId":{"type":"string","description":"Next router to chain to (or \"apiRouter\" for final routing)"},"pageProcessors":{"type":"array","description":"Processing steps to execute in this branch","items":{"type":"object","properties":{"type":{"type":"string","enum":["export","import"],"description":"Type of processor"},"_exportId":{"type":"string","format":"objectId","description":"Export resource reference (when type=\"export\")."},"_importId":{"type":"string","format":"objectId","description":"Import resource reference (when type=\"import\")."},"hooks":{"type":"object","description":"Custom scripts for processing"}}}}}}}},"required":["branches"]},"ResponseRouter":{"type":"object","description":"Final routing step that selects which response configuration to return.\nMust have `id: \"apiRouter\"`.","properties":{"id":{"type":"string","enum":["apiRouter"],"description":"Must be `\"apiRouter\"`."},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to determine which response to use."},"script":{"type":"object","description":"Script configuration when `routeRecordsUsing` is `\"script\"`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the response id."}}}}},"ApiResponse":{"type":"object","description":"Response configuration in a builder-mode API. Each API requires exactly one\n`success` and one `fail` response; additional `custom` responses are optional.","properties":{"id":{"type":"string","description":"Unique identifier for this response, referenced by the response router."},"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description of when this response is used."},"type":{"type":"string","enum":["success","fail","custom"],"description":"Response type."},"statusCode":{"type":"integer","minimum":100,"maximum":599,"description":"HTTP status code to return."},"headers":{"type":"array","description":"Response headers to include.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"value":{"type":"string","maxLength":256,"description":"Header value (can include handlebars templates)"},"description":{"type":"string","maxLength":10240,"description":"Description of the header"}}}},"inputFilter":{"type":"object","description":"Filter criteria for response selection by the response router.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the response body structure. Every object-typed\nschema node must declare at least one property for the API Builder to\nrender it; omit this field when the response body has no defined shape.","additionalProperties":true},"mockInput":{"type":["object","string"],"maxLength":0,"description":"Mock data for testing this response, in the integrator.io canonical\nrecord-page format: `{\"page_of_records\": [{\"record\": {...}}, ...]}`.\nThe server rejects any other object shape and any non-empty string\nwith a 422; the empty string `\"\"` (a UI draft artifact) is accepted\nand stored verbatim.","required":["page_of_records"],"properties":{"page_of_records":{"type":"array","description":"Pages of mock records fed to this response's mappings.","items":{"type":"object","required":["record"],"properties":{"record":{"type":"object","description":"One mock input record (freeform payload)."},"success":{"type":"boolean","description":"When true, the mock record follows the success path."},"testMode":{"type":"boolean","description":"When true, the mock record is treated as a test-mode record."}}}}},"additionalProperties":true},"mappings":{"type":"array","description":"Field mappings to transform processing results into the response body.","items":{"type":"object","required":["dataType"],"properties":{"generate":{"type":"string","description":"Target field path in the response"},"dataType":{"type":"string","enum":["string","number","boolean","object","stringarray","numberarray","booleanarray","objectarray","arrayarray"],"description":"Data type of the value this mapping writes into the response body."},"extract":{"type":"string","description":"Source field path from input data"},"hardCodedValue":{"type":"string","description":"Static value written to the target field instead of extracting\nfrom input data."}}}},"lookups":{"type":"array","description":"Static key-value lookup tables for value transformation.","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the lookup"},"map":{"type":"object","description":"Key-value mapping object"},"default":{"type":"string","description":"Default value if key not found"},"allowFailures":{"type":"boolean","description":"When true, processing continues even if this lookup fails."}}}},"hooks":{"type":"object","description":"Custom scripts to run during response processing.","properties":{"preMap":{"type":"object","description":"Script to run before applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}},"postMap":{"type":"object","description":"Script to run after applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}}}}}},"Shipworks":{"type":"object","description":"ShipWorks shipping-management credentials. Legacy feature.","properties":{"username":{"type":"string","description":"ShipWorks username."},"password":{"type":"string","description":"ShipWorks password. Masked as `\"******\"` in GET responses."}},"required":["username","password"]},"Apim":{"type":"array","readOnly":true,"description":"Publication status of this API in external API management systems.","items":{"type":"object","properties":{"apiId":{"type":"string","description":"Identifier assigned by the external API management system (a UUID, not a Celigo API _id)."},"flowId":{"type":"string","description":"Associated flow identifier in the external API management system (a UUID, not a Celigo flow _id). Empty when no flow is associated."},"status":{"type":"string","enum":["oaspending","published"],"description":"Publication status."},"definitionVersion":{"type":"string","enum":["v4"],"description":"API definition format version."}}}},"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/apis/{_id}":{"get":{"summary":"Get an API","description":"Returns the complete configuration of a specific API.","operationId":"getApiById","tags":["APIs"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the API","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"API retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/API"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Update an API

> Replaces the full API configuration. Send the complete object -- omitted fields revert to\
> defaults, not their prior values. Read-only fields (\`\_id\`, \`createdAt\`, \`lastModified\`) in\
> the request body are ignored.\
> \
> \`logging\` is also ignored -- silently: a PUT that includes \`logging\` succeeds with the\
> stored value unchanged, and no error reveals that the change was dropped. Use\
> \`PATCH /v1/apis/{\_id}\` (paths \`/logging/mode\`, \`/logging/debugUntil\`) to change logging\
> settings.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Request":{"type":"object","description":"Request body for creating or updating an API.\n\nFor builder-mode APIs, populate the `builder` object (at minimum\n`builder.request.relativeURI` and `builder.request.method`); the `script`\nfield is ignored. For script-mode APIs, populate `script` with `_scriptId`\nand `function`; the `builder` field is ignored. On PUT, send the complete\nobject — omitted fields revert to defaults.\n\nSet `type` explicitly to `builder` or `script`. The server infers `script`\nwhen `type` is omitted, but new APIs must declare it.","required":["name","type"],"allOf":[{"$ref":"#/components/schemas/APIBase"}]},"APIBase":{"type":"object","description":"Writable fields shared by the request and response schemas.","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Display name."},"_integrationId":{"type":["string","null"],"format":"objectId","description":"Integration this API belongs to. **Builder mode only** — a script-mode\nAPI is always account-level and the server silently drops this field.\nSend `null` (or omit) to keep the API account-level; on reads the field\nis omitted when unset, never `null`."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"One of the owning integration's `apiGroupings`, subdividing its APIs.\nRequires `_integrationId` in the same write — sent without it, the server\nsilently drops both — so builder mode only. `PUT /v1/apis/updateApiGrouping`\nregroups many APIs at once; this field carries the same value on a single\nAPI. On reads the field is omitted when unset, never `null`."},"description":{"type":"string","description":"Optional description of the API's purpose."},"type":{"type":"string","enum":["builder","script"],"default":"script","description":"API mode. Cannot be changed after creation. Defaults to `script` when\nomitted on create; legacy script APIs created before builder mode may\nomit it on reads as well."},"version":{"type":"string","default":"v1","pattern":"^[a-zA-Z0-9\\-_\\.]+$","description":"Version segment of the public URL (`/{version}/{relativeURI}`)."},"disabled":{"type":"boolean","default":false,"description":"When true, the API rejects all incoming requests."},"timeoutPeriod":{"type":"integer","minimum":0,"maximum":120,"description":"Request-timeout override in seconds (1–120). `0` is a sentinel meaning \"use the\n120-second default\" — the server rewrites it on write, so a stored value is never 0."},"logging":{"type":"object","description":"Execution-logging settings for the API. Builder-mode APIs are\ninitialized to `{\"mode\": \"basic\"}` at creation (when the account\nlicense has logging enabled), so the field is present on responses\nfrom the start.\n\nPOST and PUT bodies cannot set or change this field — the server\nignores it silently (the write succeeds and the stored value is\nuntouched). `PATCH /v1/apis/{_id}` with the `/logging/mode` and\n`/logging/debugUntil` paths is the only way to change it.","properties":{"mode":{"type":"string","enum":["basic","standard","detailed","accountLevel","noLogging"],"description":"Which logging level applies to requests handled by this API. Only\n`detailed` (or a temporary debug window) produces the per-step\ntrace data used by `GET /v1/apis/{_id}/requests/{executionId}`.\nPayload-capturing modes (`standard`, `detailed`) require payload\nstorage to be enabled for the account — without it, changing the\nmode fails with `422` (code `payload_storage_required`)."},"debugUntil":{"type":"string","format":"date-time","description":"While this timestamp is in the future, requests are captured in\nfull debug mode regardless of `mode`. Clears itself once the\nwindow passes. Setting it requires payload storage to be enabled\nfor the account."}}},"traceKeyTemplate":{"type":"string","maxLength":1024,"description":"Handlebars template that computes each request's trace key from the\nrequest payload, used to correlate run-history entries with source\nrecords. Absent from responses until set."},"pagination":{"type":"object","description":"Cursor pagination for builder-mode APIs whose volume-driver lookup\nsupports paging. When enabled, API responses are wrapped in a\n`{data, pagination: {has_more, next_cursor}}` envelope; consumers\nresume by sending `next_cursor` in the POST body (or the\n`Celigo-Next-Cursor` header on GET) until `has_more` is false.\nInvalid or mismatched cursors fail with `invalid_cursor_format`,\n`cursor_version_unsupported`, `cursor_signature_invalid`,\n`cursor_api_mismatch`, `cursor_filter_mismatch`, or\n`cursor_not_supported_for_api`. Absent from responses until set.","properties":{"enabled":{"type":"boolean","description":"When true, the pagination envelope and cursor contract are active for this API."}}},"script":{"$ref":"#/components/schemas/Script"},"builder":{"$ref":"#/components/schemas/Builder"},"shipworks":{"$ref":"#/components/schemas/Shipworks"},"draft":{"type":"boolean","description":"When true, this API is a draft that auto-deletes when its expiry passes\n(`draftExpiresAt` in the response). Set at creation; an update can clear the\nflag but never set it."}}},"Script":{"type":"object","description":"Script-mode configuration. The referenced function receives the request object\nand must return a response with `statusCode`, `headers`, and `body`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource containing the handler function."},"function":{"type":"string","description":"Name of the function to invoke within the script."}},"required":["_scriptId","function"]},"Builder":{"type":"object","description":"Builder-mode configuration defining request structure, routing, and response mapping.","properties":{"request":{"$ref":"#/components/schemas/ApiRequest"},"routers":{"type":"array","description":"Optional routers for conditional processing before the response stage.","items":{"$ref":"#/components/schemas/Router"}},"responseRouter":{"$ref":"#/components/schemas/ResponseRouter"},"responses":{"type":"array","description":"Response configurations. Must include exactly one `success` and one `fail`\nresponse; additional `custom` responses are optional.","items":{"$ref":"#/components/schemas/ApiResponse"}}}},"ApiRequest":{"type":"object","description":"Request configuration for a builder-mode API endpoint.","properties":{"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description."},"relativeURI":{"type":"string","maxLength":131072,"pattern":"^\\/[a-zA-Z0-9:_*\\/\\-\\.]*$","description":"URI path relative to the version. Full endpoint becomes\n`/{version}{relativeURI}`. Use colon notation for path params: `/customers/:id`."},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for the API endpoint."},"headers":{"type":"array","description":"Expected request headers.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"description":{"type":"string","maxLength":10240,"description":"Description of the header's purpose"}}}},"pathParams":{"type":"array","description":"Path parameters defined in the `relativeURI`.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"description":"Parameter name (without the colon prefix)"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"queryParams":{"type":"array","description":"Expected query string parameters.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_\\-:\\/]*$","description":"Query parameter name"},"dataType":{"type":"string","enum":["string","number","boolean"],"description":"Expected data type of the parameter"},"description":{"type":"string","maxLength":10240,"description":"Description of the parameter"}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the expected request body structure. Every\nobject-typed schema node must declare at least one property for the\nAPI Builder to render it; omit this field when the endpoint has no\nbody contract.","additionalProperties":true},"mockRequest":{"type":"object","description":"Mock request data for testing the API without live calls.","properties":{"body":{"type":"object","description":"Sample request body"},"headers":{"type":"object","description":"Sample headers"},"pathParams":{"type":"object","description":"Sample path parameters"},"queryParams":{"type":"object","description":"Sample query parameters"}},"additionalProperties":false},"transform":{"type":"object","description":"Optional transformation applied to the incoming request before processing.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to a script for custom transformation logic."},"function":{"type":"string","description":"Function name in the script to execute."}}}},"required":["relativeURI","method"]},"Router":{"type":"object","description":"Conditional routing within a builder-mode API. Unlike flows, APIs only\nsupport `first_matching_branch` routing.","properties":{"id":{"type":"string","description":"Unique identifier for this router within the API."},"name":{"type":"string","description":"Display name."},"routeRecordsTo":{"type":"string","enum":["first_matching_branch"],"description":"Routing strategy. APIs only support `first_matching_branch`.","default":"first_matching_branch"},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to evaluate routing criteria.","default":"input_filters"},"script":{"type":"object","description":"Script configuration when routeRecordsUsing=\"script\".\n","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the branch name."}}},"branches":{"type":"array","description":"Processing branches, evaluated in order.","items":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"inputFilter":{"type":"object","description":"Filter criteria for branch selection.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"nextRouterId":{"type":"string","description":"Next router to chain to (or \"apiRouter\" for final routing)"},"pageProcessors":{"type":"array","description":"Processing steps to execute in this branch","items":{"type":"object","properties":{"type":{"type":"string","enum":["export","import"],"description":"Type of processor"},"_exportId":{"type":"string","format":"objectId","description":"Export resource reference (when type=\"export\")."},"_importId":{"type":"string","format":"objectId","description":"Import resource reference (when type=\"import\")."},"hooks":{"type":"object","description":"Custom scripts for processing"}}}}}}}},"required":["branches"]},"ResponseRouter":{"type":"object","description":"Final routing step that selects which response configuration to return.\nMust have `id: \"apiRouter\"`.","properties":{"id":{"type":"string","enum":["apiRouter"],"description":"Must be `\"apiRouter\"`."},"routeRecordsUsing":{"type":"string","enum":["input_filters","script"],"description":"Method used to determine which response to use."},"script":{"type":"object","description":"Script configuration when `routeRecordsUsing` is `\"script\"`.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name that returns the response id."}}}}},"ApiResponse":{"type":"object","description":"Response configuration in a builder-mode API. Each API requires exactly one\n`success` and one `fail` response; additional `custom` responses are optional.","properties":{"id":{"type":"string","description":"Unique identifier for this response, referenced by the response router."},"name":{"type":"string","maxLength":200,"description":"Display name."},"description":{"type":"string","maxLength":10240,"description":"Optional description of when this response is used."},"type":{"type":"string","enum":["success","fail","custom"],"description":"Response type."},"statusCode":{"type":"integer","minimum":100,"maximum":599,"description":"HTTP status code to return."},"headers":{"type":"array","description":"Response headers to include.","items":{"type":"object","properties":{"key":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9_-]+$","description":"Header name"},"value":{"type":"string","maxLength":256,"description":"Header value (can include handlebars templates)"},"description":{"type":"string","maxLength":10240,"description":"Description of the header"}}}},"inputFilter":{"type":"object","description":"Filter criteria for response selection by the response router.","properties":{"version":{"type":"string","enum":["1"],"description":"Version of the filter format used by `rules`."},"rules":{"type":"array","description":"Celigo expression-based filter rules.","items":{}}}},"bodySchema":{"type":"object","description":"JSON Schema describing the response body structure. Every object-typed\nschema node must declare at least one property for the API Builder to\nrender it; omit this field when the response body has no defined shape.","additionalProperties":true},"mockInput":{"type":["object","string"],"maxLength":0,"description":"Mock data for testing this response, in the integrator.io canonical\nrecord-page format: `{\"page_of_records\": [{\"record\": {...}}, ...]}`.\nThe server rejects any other object shape and any non-empty string\nwith a 422; the empty string `\"\"` (a UI draft artifact) is accepted\nand stored verbatim.","required":["page_of_records"],"properties":{"page_of_records":{"type":"array","description":"Pages of mock records fed to this response's mappings.","items":{"type":"object","required":["record"],"properties":{"record":{"type":"object","description":"One mock input record (freeform payload)."},"success":{"type":"boolean","description":"When true, the mock record follows the success path."},"testMode":{"type":"boolean","description":"When true, the mock record is treated as a test-mode record."}}}}},"additionalProperties":true},"mappings":{"type":"array","description":"Field mappings to transform processing results into the response body.","items":{"type":"object","required":["dataType"],"properties":{"generate":{"type":"string","description":"Target field path in the response"},"dataType":{"type":"string","enum":["string","number","boolean","object","stringarray","numberarray","booleanarray","objectarray","arrayarray"],"description":"Data type of the value this mapping writes into the response body."},"extract":{"type":"string","description":"Source field path from input data"},"hardCodedValue":{"type":"string","description":"Static value written to the target field instead of extracting\nfrom input data."}}}},"lookups":{"type":"array","description":"Static key-value lookup tables for value transformation.","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the lookup"},"map":{"type":"object","description":"Key-value mapping object"},"default":{"type":"string","description":"Default value if key not found"},"allowFailures":{"type":"boolean","description":"When true, processing continues even if this lookup fails."}}}},"hooks":{"type":"object","description":"Custom scripts to run during response processing.","properties":{"preMap":{"type":"object","description":"Script to run before applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}},"postMap":{"type":"object","description":"Script to run after applying mappings.","properties":{"_scriptId":{"type":"string","format":"objectId","description":"Reference to the script resource."},"function":{"type":"string","description":"Function name to execute."}}}}}}},"Shipworks":{"type":"object","description":"ShipWorks shipping-management credentials. Legacy feature.","properties":{"username":{"type":"string","description":"ShipWorks username."},"password":{"type":"string","description":"ShipWorks password. Masked as `\"******\"` in GET responses."}},"required":["username","password"]},"API":{"required":["_id","name","createdAt","lastModified"],"description":"API resource. Shape varies by mode: builder-mode APIs carry `type`, `version`,\n`disabled`, and `builder`; script-mode APIs additionally carry `script` plus\ntop-level `_scriptId` / `function` copies. Legacy script APIs (pre-builder era)\nomit `type`, `version`, `disabled`, and `builder` entirely.","allOf":[{"$ref":"#/components/schemas/APIBase"},{"type":"object","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the API."},"_scriptId":{"type":"string","format":"objectId","readOnly":true,"description":"Top-level copy of `script._scriptId`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"function":{"type":"string","readOnly":true,"description":"Top-level copy of `script.function`. Present on script-mode and legacy\nscript APIs for backward compatibility."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was created."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the API was last modified."},"_templateId":{"type":"string","format":"objectId","readOnly":true,"description":"Template this API was created from. Present only on template-installed APIs."},"draftExpiresAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when a draft API auto-deletes. Server-computed when `draft` is set at\ncreation."},"apim":{"$ref":"#/components/schemas/Apim"}}}]},"Apim":{"type":"array","readOnly":true,"description":"Publication status of this API in external API management systems.","items":{"type":"object","properties":{"apiId":{"type":"string","description":"Identifier assigned by the external API management system (a UUID, not a Celigo API _id)."},"flowId":{"type":"string","description":"Associated flow identifier in the external API management system (a UUID, not a Celigo flow _id). Empty when no flow is associated."},"status":{"type":"string","enum":["oaspending","published"],"description":"Publication status."},"definitionVersion":{"type":"string","enum":["v4"],"description":"API definition format version."}}}},"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"}}}},"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/apis/{_id}":{"put":{"summary":"Update an API","description":"Replaces the full API configuration. Send the complete object -- omitted fields revert to\ndefaults, not their prior values. Read-only fields (`_id`, `createdAt`, `lastModified`) in\nthe request body are ignored.\n\n`logging` is also ignored -- silently: a PUT that includes `logging` succeeds with the\nstored value unchanged, and no error reveals that the change was dropped. Use\n`PATCH /v1/apis/{_id}` (paths `/logging/mode`, `/logging/debugUntil`) to change logging\nsettings.","operationId":"updateApi","tags":["APIs"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the API","required":true,"schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"responses":{"200":{"description":"API updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/API"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Delete an API

> Deletes an API. Soft-deleted and retained in the recycle bin for 30 days. The public endpoint\
> stops responding immediately. The delete succeeds even with dependents, but those resources\
> will break -- check \`GET /v1/apis/{\_id}/dependencies\` first.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/apis/{_id}":{"delete":{"summary":"Delete an API","description":"Deletes an API. Soft-deleted and retained in the recycle bin for 30 days. The public endpoint\nstops responding immediately. The delete succeeds even with dependents, but those resources\nwill break -- check `GET /v1/apis/{_id}/dependencies` first.","operationId":"deleteApi","tags":["APIs"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the API","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"API deleted successfully"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Patch an API

> Partially updates an API using a JSON Patch document (RFC 6902).\
> The \`replace\` operation is supported on the following whitelisted\
> paths (\`/logging/debugUntil\` also accepts \`remove\`, which clears an\
> active debug window early):\
> \
> \| Path | Description |\
> \|------|-------------|\
> \| \`/name\` | API display name |\
> \| \`/description\` | API description |\
> \| \`/disabled\` | Enable or disable the API (boolean) |\
> \| \`/timeoutPeriod\` | Request-timeout override in seconds |\
> \| \`/pagination/enabled\` | Enable or disable the cursor-pagination envelope (boolean) |\
> \| \`/logging/mode\` | Logging level for requests handled by this API |\
> \| \`/logging/debugUntil\` | End of a temporary full-debug capture window |\
> \| \`/traceKeyTemplate\` | Handlebars template that computes each request's trace key |\
> \
> All other paths are rejected with \`422\`. This is the only way to change\
> \`logging\` -- PUT silently ignores that field.\
> \
> Logging changes are validated against account entitlements: setting\
> \`/logging/mode\` to a payload-capturing mode (\`standard\`, \`detailed\`)\
> fails with \`422\` (code \`payload\_storage\_required\`) when the account\
> does not have payload storage enabled, and \`/logging/debugUntil\` has\
> the same payload-storage requirement. Accounts whose license does not\
> include logging, or whose license caps the maximum logging mode below\
> the requested one, are also rejected with \`422\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"JsonPatchRequest":{"type":"array","description":"A JSON Patch document (RFC 6902). Send an array of patch\noperations on whitelisted fields — all other paths are rejected\nwith 422.","minItems":1,"items":{"$ref":"#/components/schemas/JsonPatchOperation"}},"JsonPatchOperation":{"type":"object","description":"A single JSON Patch operation (RFC 6902).","required":["op","path"],"properties":{"op":{"type":"string","enum":["replace","add","remove"],"description":"The operation to perform."},"path":{"type":"string","description":"JSON Pointer (RFC 6901) to the field to patch. Only\nwhitelisted paths are accepted — unlisted paths return\n`422` with `\"<path> is not a whitelisted property\"`."},"value":{"description":"The new value to set. Required for `replace` and `add`, omit for `remove`."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/apis/{_id}":{"patch":{"summary":"Patch an API","description":"Partially updates an API using a JSON Patch document (RFC 6902).\nThe `replace` operation is supported on the following whitelisted\npaths (`/logging/debugUntil` also accepts `remove`, which clears an\nactive debug window early):\n\n| Path | Description |\n|------|-------------|\n| `/name` | API display name |\n| `/description` | API description |\n| `/disabled` | Enable or disable the API (boolean) |\n| `/timeoutPeriod` | Request-timeout override in seconds |\n| `/pagination/enabled` | Enable or disable the cursor-pagination envelope (boolean) |\n| `/logging/mode` | Logging level for requests handled by this API |\n| `/logging/debugUntil` | End of a temporary full-debug capture window |\n| `/traceKeyTemplate` | Handlebars template that computes each request's trace key |\n\nAll other paths are rejected with `422`. This is the only way to change\n`logging` -- PUT silently ignores that field.\n\nLogging changes are validated against account entitlements: setting\n`/logging/mode` to a payload-capturing mode (`standard`, `detailed`)\nfails with `422` (code `payload_storage_required`) when the account\ndoes not have payload storage enabled, and `/logging/debugUntil` has\nthe same payload-storage requirement. Accounts whose license does not\ninclude logging, or whose license caps the maximum logging mode below\nthe requested one, are also rejected with `422`.","operationId":"patchApi","tags":["APIs"],"parameters":[{"name":"_id","in":"path","description":"The unique identifier of the API","required":true,"schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonPatchRequest"}}}},"responses":{"204":{"description":"API patched successfully"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Convert a JSON object to JSON Schema

> Accepts a sample JSON object and returns its inferred JSON Schema definition.\
> Useful for bootstrapping \`bodySchema\` in builder-mode APIs from real payload samples.\
> Input must be a non-empty JSON object -- arrays and primitives are rejected.\
> The generated schema is shallow (one level of \`properties\`); nested objects become\
> \`type: "object"\` without further property inference.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"422-unprocessable-entity":{"description":"Unprocessable entity. The request was well-formed but was unable to be followed due to semantic errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"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/apis/schema":{"put":{"operationId":"convertJsonToSchema","tags":["APIs"],"summary":"Convert a JSON object to JSON Schema","description":"Accepts a sample JSON object and returns its inferred JSON Schema definition.\nUseful for bootstrapping `bodySchema` in builder-mode APIs from real payload samples.\nInput must be a non-empty JSON object -- arrays and primitives are rejected.\nThe generated schema is shallow (one level of `properties`); nested objects become\n`type: \"object\"` without further property inference.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Any sample JSON object to convert into JSON Schema."}}}},"responses":{"200":{"description":"JSON Schema generated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"properties":{"type":"object","additionalProperties":true}},"additionalProperties":true}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Update the grouping for one or more APIs

> Assigns or removes an API grouping for the specified API resources. Pass\
> \`\_apiGroupingId: null\` to ungroup. Nonexistent API IDs are silently accepted.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"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"]}}}}},"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/apis/updateApiGrouping":{"put":{"operationId":"updateApiGrouping","tags":["APIs"],"summary":"Update the grouping for one or more APIs","description":"Assigns or removes an API grouping for the specified API resources. Pass\n`_apiGroupingId: null` to ungroup. Nonexistent API IDs are silently accepted.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["_apiIds"],"properties":{"_apiIds":{"type":"array","items":{"type":"string","format":"objectId"},"description":"List of API resource IDs to update."},"_apiGroupingId":{"type":["string","null"],"format":"objectId","description":"The grouping ID to assign. Pass `null` or omit to remove the\ncurrent grouping from the specified APIs."}}}}}},"responses":{"204":{"description":"API grouping updated successfully (no body returned)."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## List recent request/response logs for an API

> Returns the recent invocation traces captured for the named API. Each entry is a decoded\
> request/response pair — masked for credentials — that the runtime stored when the API was\
> called via its public endpoint. Use this to audit what the API has handled and to triage\
> errors without re-invoking the API.\
> \
> Traces are \*\*file-backed\*\* with server-controlled retention and capture scope; an empty\
> \`requests\[]\` simply means nothing is currently stored for this API. Two invocation sources do\
> \*\*not\*\* populate this log:\
> \- Test-runs via \`POST /v1/apis/{\_id}/test/run\` never surface here.\
> \- Script-mode API invocations via \`POST /v1/apis/{\_id}/request\` also do not surface here\
> &#x20; despite counting toward \`/v1/apis/usage\`. Only \*\*builder-mode\*\* invocations against the\
> &#x20; public endpoint (\`<https://api.integrator.io/apis/{version}{relativeURI}\\`>) populate logs.\
> \
> List entries are \*\*summaries\*\* (\`key\`, \`time\`, \`method\`, \`statusCode\`) — to see the decoded\
> request/response payload, follow up with \`GET /v1/apis/{\_id}/logs/{key}\`.\
> \
> \`statusCode\` is returned as a string in list entries but as an integer on the detail endpoint.\
> Credential values are masked as \`\*\*\*\*\*\*\*\*\` before storage and are not recoverable.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiLogsResponse":{"type":"object","description":"Request log envelope returned by `GET /v1/apis/{_id}/logs`. Contains the recent API invocation\ntraces for the API identified by `_id`. The `requests[]` array is empty when no invocations\nhave been logged — either the API has never been called, or debug capture is off, or the\nretention window has elapsed. Each entry is a full decoded request/response pair.","properties":{"requests":{"type":"array","description":"Invocation summaries, newest first. Each entry has just `{key, time, method, statusCode}`;\nthe decoded request/response payload lives behind `GET /v1/apis/{_id}/logs/{key}`.","items":{"$ref":"#/components/schemas/ApiLogEntry"}}}},"ApiLogEntry":{"type":"object","description":"Summary row returned in the `GET /v1/apis/{_id}/logs` listing. Carries just enough to identify\neach invocation (when it ran, how it ended) so the caller can pick which ones to inspect in\nfull via `GET /v1/apis/{_id}/logs/{key}`. Full request/response payloads are **not** in the\nlist — only in the detail fetch.","properties":{"key":{"type":"string","description":"Opaque log key. Pass to `GET /v1/apis/{_id}/logs/{key}` to retrieve the full decoded\ntransaction. Structure is `<seq>-<id>-<status>-<method>` (e.g.\n`5481201053696-a10af1ade8fe477a847771c1e3716e36-200-POST`). The embedded `<id>` also\nappears as `id` on the detail response."},"time":{"type":"integer","format":"int64","description":"Epoch milliseconds when the invocation was handled."},"method":{"type":"string","description":"HTTP method of the inbound request (`GET`, `POST`, ...)."},"statusCode":{"type":"string","description":"HTTP status code the API returned to the caller, as a **string** (e.g. `\"200\"`). Note: on\nthe detail endpoint this same value is exposed as an integer under `response.statusCode` —\nthe list surfaces it as a 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"]}}}},"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/apis/{_id}/logs":{"get":{"operationId":"listApiLogs","tags":["APIs"],"summary":"List recent request/response logs for an API","description":"Returns the recent invocation traces captured for the named API. Each entry is a decoded\nrequest/response pair — masked for credentials — that the runtime stored when the API was\ncalled via its public endpoint. Use this to audit what the API has handled and to triage\nerrors without re-invoking the API.\n\nTraces are **file-backed** with server-controlled retention and capture scope; an empty\n`requests[]` simply means nothing is currently stored for this API. Two invocation sources do\n**not** populate this log:\n- Test-runs via `POST /v1/apis/{_id}/test/run` never surface here.\n- Script-mode API invocations via `POST /v1/apis/{_id}/request` also do not surface here\n  despite counting toward `/v1/apis/usage`. Only **builder-mode** invocations against the\n  public endpoint (`https://api.integrator.io/apis/{version}{relativeURI}`) populate logs.\n\nList entries are **summaries** (`key`, `time`, `method`, `statusCode`) — to see the decoded\nrequest/response payload, follow up with `GET /v1/apis/{_id}/logs/{key}`.\n\n`statusCode` is returned as a string in list entries but as an integer on the detail endpoint.\nCredential values are masked as `********` before storage and are not recoverable.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Trace envelope. `requests[]` is empty when no invocations are currently stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLogsResponse"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get one request/response log entry by key

> Returns the full decoded request/response envelope for one API invocation, looked up by the\
> opaque \`key\` values surfaced in \`GET /v1/apis/{\_id}/logs\`. Matches the exact entry whose key is\
> provided — there is no partial-match or range query on this endpoint.\
> \
> Unlike the parent list (which only carries \`{key, time, method, statusCode}\`), this endpoint\
> returns the complete payload: request method/url/headers/body/queryParams/clientAddress,\
> response status/headers/body/responseTime, and (for builder-mode APIs) the\
> \`inputToResponseBubble\` snapshot of what the response-mapper saw. Sensitive header values\
> (\`authorization\`, OAuth bearer tokens) are masked as \`\*\*\*\*\*\*\*\*\` before storage.\
> \
> For builder APIs where the response mapper didn't produce the expected output, inspect\
> \`inputToResponseBubble.sourceRecord\` to see what the response stage actually received.\
> \`response.statusCode\` is an integer here but the sibling list endpoint returns it as a\
> string. A 404 \`file\_not\_found\` means the key has expired from retention or was never\
> captured.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiLogDetail":{"type":"object","description":"Full decoded request/response envelope for one API invocation, returned by\n`GET /v1/apis/{_id}/logs/{key}`. Sensitive header values (`authorization`, OAuth bearer tokens,\nand similar) are masked with `********` before storage — the originals are not recoverable.\nThe `inputToResponseBubble` block reveals the Celigo-internal state handed to the\nresponse-mapping stage; it's absent for script-mode APIs and pre-mapping failures.","properties":{"time":{"type":"integer","format":"int64","description":"Epoch milliseconds when the invocation was handled."},"request":{"type":"object","description":"The inbound HTTP request the API received, as decoded by the runtime.","properties":{"method":{"type":"string","description":"HTTP method of the inbound request."},"url":{"type":"string","description":"The path the caller hit, relative to `https://api.integrator.io`. Includes the API\n`{version}` and the API's configured `relativeURI` (e.g. `/apis/v1/hubspot`).\nQuery-string credentials are masked before storage."},"httpVersion":{"type":"string","description":"HTTP protocol version the caller negotiated (e.g. `1.1`, `2`)."},"headers":{"type":"object","description":"Inbound headers. The `authorization` header (and other credential headers) are masked.","additionalProperties":{"type":"string"}},"queryParams":{"type":"object","description":"Parsed query-string parameters. Empty object when none were sent.","additionalProperties":true},"body":{"type":"string","description":"Request body as received, verbatim string (JSON payloads arrive already serialized —\nparse with `JSON.parse` when you need structured data). Empty string for bodyless\nmethods."},"clientAddress":{"type":"string","description":"IP the request arrived from, as the Celigo edge saw it. IPv6 format; may be a\nprivate/loopback address (e.g. `::ffff:127.0.0.6`) when routed through an internal\nproxy rather than the public internet."},"size":{"type":"integer","description":"Byte size the runtime recorded for the request. Often `0` — this field is not consistently populated."}}},"response":{"type":"object","description":"The outbound HTTP response the API produced.","properties":{"statusCode":{"type":"integer","description":"HTTP status code returned to the caller, as an **integer** here. Note the list endpoint\n(`GET /v1/apis/{_id}/logs`) exposes the same value as a string."},"statusMessage":{"type":"string","description":"HTTP status reason phrase (`OK`, `Bad Request`, ...)."},"headers":{"type":"object","description":"Response headers sent to the caller.","additionalProperties":{"type":"string"}},"body":{"type":"string","description":"Response body as sent. String form; parse as JSON/XML per the `content-type` header."},"size":{"type":"integer","description":"Byte size of the serialized response body."},"responseTime":{"type":"integer","description":"Total time in milliseconds from request arrival to response flush."}}},"inputToResponseBubble":{"type":"object","description":"Builder-mode APIs only. Snapshot of the state handed to the response-mapping stage — the\nparsed input records plus any execution/configuration errors collected along the pipeline.\nUse this to debug response-mapping issues (\"what did the mapper actually see?\"). Absent on\nscript-mode APIs.","properties":{"sourceRecord":{"description":"Array of records (or single-record object) that the response-mapper was given as input."},"executionErrors":{"type":"array","description":"Runtime errors raised during processing (e.g. script exceptions, lookup failures).","items":{"type":"object","additionalProperties":true}},"configurationErrors":{"type":"array","description":"Configuration errors detected before execution (e.g. missing required mapping fields).","items":{"type":"object","additionalProperties":true}}}},"key":{"type":"string","description":"Echoes the `key` path parameter. Same structure as in the list (`<seq>-<id>-<status>-<method>`)."},"id":{"type":"string","description":"Shorter internal id for this log record. Appears embedded in the `key` string as the second\nsegment. Not independently useful to the caller, but handy for correlating with audit or\nmonitoring logs that reference only the short id."}}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/apis/{_id}/logs/{key}":{"get":{"operationId":"getApiLogByKey","tags":["APIs"],"summary":"Get one request/response log entry by key","description":"Returns the full decoded request/response envelope for one API invocation, looked up by the\nopaque `key` values surfaced in `GET /v1/apis/{_id}/logs`. Matches the exact entry whose key is\nprovided — there is no partial-match or range query on this endpoint.\n\nUnlike the parent list (which only carries `{key, time, method, statusCode}`), this endpoint\nreturns the complete payload: request method/url/headers/body/queryParams/clientAddress,\nresponse status/headers/body/responseTime, and (for builder-mode APIs) the\n`inputToResponseBubble` snapshot of what the response-mapper saw. Sensitive header values\n(`authorization`, OAuth bearer tokens) are masked as `********` before storage.\n\nFor builder APIs where the response mapper didn't produce the expected output, inspect\n`inputToResponseBubble.sourceRecord` to see what the response stage actually received.\n`response.statusCode` is an integer here but the sibling list endpoint returns it as a\nstring. A 404 `file_not_found` means the key has expired from retention or was never\ncaptured.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"key","in":"path","required":true,"description":"Opaque log key from the parent `GET /v1/apis/{_id}/logs` listing. Encodes status + method\n(e.g. `…-200-POST`) — use the `key` exactly as returned; do not construct one manually.","schema":{"type":"string"}}],"responses":{"200":{"description":"The decoded request/response envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLogDetail"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## List API request run history (defaults to last 5 minutes)

> Returns the logged request executions for an API — one entry per inbound\
> request captured while the API's \`logging.mode\` was anything other than\
> \`noLogging\`. Distinct from \`GET /v1/apis/{\_id}/logs\`, which returns the\
> legacy file-backed request/response envelopes: use \`/requests\` for run\
> history and trace drill-down, \`/logs\` for the raw decoded request and\
> response of a single call.\
> \
> Whether requests are captured into run history depends on server-side\
> enablement of the capture pipeline, which is separate from this read\
> API. On accounts where capture is not active, this endpoint responds\
> normally (including filter validation) but \`requests\` is empty\
> regardless of the API's \`logging.mode\` — even for requests that the\
> legacy \`GET /v1/apis/{\_id}/logs\` (an independent capture path) does\
> record.\
> \
> Results are cursor-paginated (\`next\`/\`prev\`). When \`time\_gte\` / \`time\_lte\`\
> are omitted, only the last 5 minutes are returned — pass an explicit window\
> for a broader history. Use the \`executionId\` from a list entry with\
> \`GET /v1/apis/{\_id}/requests/{executionId}\` to open the trace view for\
> requests logged in \`detailed\` or \`debug\` mode.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiRunHistoryResponse":{"type":"object","description":"Paginated API request run history.","required":["requests"],"properties":{"requests":{"type":"array","description":"Logged request executions, newest first by default.","items":{"$ref":"#/components/schemas/ApiRequestLogEntry"}},"nextPageUrl":{"type":["string","null"],"description":"URL to fetch the next page (carries the `next` cursor and\n`cursorExecutionId` tie-breaker); null when there is no next page."},"prevPageUrl":{"type":["string","null"],"description":"URL to fetch the previous page; null when there is no previous page."}}},"ApiRequestLogEntry":{"type":"object","description":"One logged API request execution in the run history.","required":["executionId","time","method","relativeURI","statusCode","timeTaken","logMode"],"properties":{"executionId":{"type":"string","description":"Identifier of this request execution (20-character lowercase hex).\nPass it to `GET /v1/apis/{_id}/requests/{executionId}` to open the\ntrace view when `logMode` is `detailed` or `debug`."},"time":{"type":"string","format":"date-time","description":"When the request was received (UTC)."},"method":{"type":"string","description":"HTTP method of the request."},"relativeURI":{"type":"string","description":"Path of the request, without scheme or host."},"statusCode":{"type":"integer","description":"HTTP status code the API responded with."},"traceKey":{"type":"string","description":"Correlation/trace key resolved for this request."},"remoteIP":{"type":"string","description":"Client IP address the request came from."},"timeTaken":{"type":"number","description":"Processing time in milliseconds."},"logMode":{"type":"string","enum":["basic","standard","detailed","debug"],"description":"Logging mode that was active when this request was processed.\nDetermines trace availability — only `detailed` and `debug` produce\nper-step trace logs. Requests processed with `no_logging` produce no\nrun-history rows at all."}}},"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests":{"get":{"operationId":"listApiRequests","tags":["APIs"],"summary":"List API request run history (defaults to last 5 minutes)","description":"Returns the logged request executions for an API — one entry per inbound\nrequest captured while the API's `logging.mode` was anything other than\n`noLogging`. Distinct from `GET /v1/apis/{_id}/logs`, which returns the\nlegacy file-backed request/response envelopes: use `/requests` for run\nhistory and trace drill-down, `/logs` for the raw decoded request and\nresponse of a single call.\n\nWhether requests are captured into run history depends on server-side\nenablement of the capture pipeline, which is separate from this read\nAPI. On accounts where capture is not active, this endpoint responds\nnormally (including filter validation) but `requests` is empty\nregardless of the API's `logging.mode` — even for requests that the\nlegacy `GET /v1/apis/{_id}/logs` (an independent capture path) does\nrecord.\n\nResults are cursor-paginated (`next`/`prev`). When `time_gte` / `time_lte`\nare omitted, only the last 5 minutes are returned — pass an explicit window\nfor a broader history. Use the `executionId` from a list entry with\n`GET /v1/apis/{_id}/requests/{executionId}` to open the trace view for\nrequests logged in `detailed` or `debug` mode.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"statusCode","in":"query","description":"Filter by HTTP response status code — a single value or a\ncomma-separated list. Every value must be an integer.","schema":{"type":"string","pattern":"^\\d+(,\\d+)*$"}},{"name":"method","in":"query","description":"Filter by HTTP method (case-insensitive; normalized to uppercase).","schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]}},{"name":"traceKey","in":"query","description":"Prefix filter on the request trace key.","schema":{"type":"string"}},{"name":"remoteIP","in":"query","description":"Prefix filter on the client IP address.","schema":{"type":"string"}},{"name":"relativeURI","in":"query","description":"Prefix filter on the request relative URI.","schema":{"type":"string"}},{"name":"searchKey","in":"query","description":"Free-text search, OR-matched across `traceKey` (prefix), `remoteIP`\n(prefix), and `relativeURI` (substring). When provided, the individual\n`traceKey`/`remoteIP`/`relativeURI` filters are ignored. Values shorter\nthan 3 characters are rejected with 400.","schema":{"type":"string","minLength":3,"maxLength":500}},{"name":"pageSize","in":"query","description":"Number of entries per page. Values above the documented maximum are\nnot rejected — the server accepts them silently, so treat the\nmaximum as the supported contract rather than an enforced limit.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"sortOrder","in":"query","description":"Sort direction by request time.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"next","in":"query","description":"ISO 8601 timestamp cursor for the next page (from `nextPageUrl`).\nMutually exclusive with `prev`; requires `cursorExecutionId`.","schema":{"type":"string","format":"date-time"}},{"name":"prev","in":"query","description":"ISO 8601 timestamp cursor for the previous page (from `prevPageUrl`).\nMutually exclusive with `next`; requires `cursorExecutionId`.","schema":{"type":"string","format":"date-time"}},{"name":"cursorExecutionId","in":"query","description":"Tie-breaker execution id, required when paging with `next`/`prev`.","schema":{"type":"string"}},{"name":"time_gte","in":"query","description":"Include requests at or after this ISO timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"time_lte","in":"query","description":"Include requests at or before this ISO timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Paginated run history. `requests[]` is empty when nothing matches.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiRunHistoryResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Delete API request logs in a date range

> Queues asynchronous deletion of stored request log payloads for the API\
> within \`\[startedAt, endAt]\`. Returns \`202 Accepted\`; cleanup runs in the\
> background. Requires manage access for log deletion — monitor-level users\
> receive \`403\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests":{"delete":{"operationId":"deleteApiRequestLogs","tags":["APIs"],"summary":"Delete API request logs in a date range","description":"Queues asynchronous deletion of stored request log payloads for the API\nwithin `[startedAt, endAt]`. Returns `202 Accepted`; cleanup runs in the\nbackground. Requires manage access for log deletion — monitor-level users\nreceive `403`.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"startedAt","in":"query","required":true,"description":"Start of the deletion range, inclusive (ISO 8601). Must be before `endAt`.","schema":{"type":"string","format":"date-time"}},{"name":"endAt","in":"query","required":true,"description":"End of the deletion range, inclusive (ISO 8601). Must not be in the future.","schema":{"type":"string","format":"date-time"}}],"responses":{"202":{"description":"Deletion request accepted for asynchronous processing."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get trace metadata for an API request execution

> Returns the top-level execution steps for the trace view of one API\
> request. Trace data is only available for requests that were logged in\
> \`detailed\` or \`debug\` mode (see \`logMode\` on the run-history entry), and\
> only when the run-history capture pipeline is active for the account\
> (see \`GET /v1/apis/{\_id}/requests\`) — otherwise \`steps\` is empty for\
> every execution id.\
> \
> A malformed \`executionId\` returns \`422\`; an unknown API \`\_id\` returns \`404\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiTraceMetadataResponse":{"type":"object","description":"Top-level execution steps for the trace view of an API request.","required":["steps"],"properties":{"steps":{"type":"array","description":"Top-level execution steps for the trace view.","items":{"$ref":"#/components/schemas/ApiRequestTraceStep"}}}},"ApiRequestTraceStep":{"type":"object","description":"A step within an API request execution trace.","required":["status","timeTaken","groupId","recordId","time"],"properties":{"_expOrImpId":{"type":"string","description":"Export, import, or builder resource-step identifier (`resStepId`) for\nthe step. Builder bubble stages use the resource-step identifier\nrather than a MongoDB ObjectId."},"status":{"type":"string","enum":["success","error","ignore"],"description":"Outcome status of the step."},"stage":{"type":"string","description":"Processing stage; present when `status` is `error` or `ignore`."},"timeTaken":{"type":"number","description":"Step processing time in milliseconds."},"groupId":{"type":"string","description":"Group identifier for the step's records."},"recordId":{"type":"string","description":"Identifier of this record."},"parentRecordId":{"type":"string","description":"Identifier of the parent record when this step is a child row."},"time":{"type":"string","format":"date-time","description":"Timestamp when the step ran (UTC)."}},"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":{"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests/{executionId}":{"get":{"operationId":"getApiRequestTrace","tags":["APIs"],"summary":"Get trace metadata for an API request execution","description":"Returns the top-level execution steps for the trace view of one API\nrequest. Trace data is only available for requests that were logged in\n`detailed` or `debug` mode (see `logMode` on the run-history entry), and\nonly when the run-history capture pipeline is active for the account\n(see `GET /v1/apis/{_id}/requests`) — otherwise `steps` is empty for\nevery execution id.\n\nA malformed `executionId` returns `422`; an unknown API `_id` returns `404`.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"executionId","in":"path","required":true,"description":"The execution id (20-character lowercase hex).","schema":{"type":"string","pattern":"^[0-9a-f]{20}$"}}],"responses":{"200":{"description":"Top-level trace steps for the request execution.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTraceMetadataResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## List child records under an API trace step

> Returns the child records under a parent record within an API request\
> trace (lookup / one-to-many expansions). Results are cursor-paginated\
> (\`next\`/\`prev\`).

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiRequestChildrenResponse":{"type":"object","description":"Paginated child records under a parent record in an API request trace.","required":["children"],"properties":{"children":{"type":"array","description":"Child step records (lookup / one-to-many expansions).","items":{"$ref":"#/components/schemas/ApiRequestTraceStep"}},"nextPageUrl":{"type":["string","null"],"description":"URL to fetch the next page; null when there is no next page."},"prevPageUrl":{"type":["string","null"],"description":"URL to fetch the previous page; null when there is no previous page."}}},"ApiRequestTraceStep":{"type":"object","description":"A step within an API request execution trace.","required":["status","timeTaken","groupId","recordId","time"],"properties":{"_expOrImpId":{"type":"string","description":"Export, import, or builder resource-step identifier (`resStepId`) for\nthe step. Builder bubble stages use the resource-step identifier\nrather than a MongoDB ObjectId."},"status":{"type":"string","enum":["success","error","ignore"],"description":"Outcome status of the step."},"stage":{"type":"string","description":"Processing stage; present when `status` is `error` or `ignore`."},"timeTaken":{"type":"number","description":"Step processing time in milliseconds."},"groupId":{"type":"string","description":"Group identifier for the step's records."},"recordId":{"type":"string","description":"Identifier of this record."},"parentRecordId":{"type":"string","description":"Identifier of the parent record when this step is a child row."},"time":{"type":"string","format":"date-time","description":"Timestamp when the step ran (UTC)."}},"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":{"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests/{executionId}/{_expOrImpId}/logs/{parentRecordId}/children":{"get":{"operationId":"listApiRequestChildren","tags":["APIs"],"summary":"List child records under an API trace step","description":"Returns the child records under a parent record within an API request\ntrace (lookup / one-to-many expansions). Results are cursor-paginated\n(`next`/`prev`).","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"executionId","in":"path","required":true,"description":"The execution id (20-character lowercase hex).","schema":{"type":"string","pattern":"^[0-9a-f]{20}$"}},{"name":"_expOrImpId","in":"path","required":true,"description":"Export, import, or builder resource-step identifier for the step.","schema":{"type":"string"}},{"name":"parentRecordId","in":"path","required":true,"description":"The parent record id whose children are returned.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter children by processing outcome — a single value or a\ncomma-separated list of `success`, `error`, `ignore`.","schema":{"type":"string","pattern":"^(success|error|ignore)(,(success|error|ignore))*$"}},{"name":"pageSize","in":"query","description":"Number of entries per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"sortOrder","in":"query","description":"Sort direction by step time.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"next","in":"query","description":"ISO 8601 timestamp cursor for the next page (from `nextPageUrl`).\nMutually exclusive with `prev`; requires `cursorRecordId`.","schema":{"type":"string","format":"date-time"}},{"name":"prev","in":"query","description":"ISO 8601 timestamp cursor for the previous page (from `prevPageUrl`).\nMutually exclusive with `next`; requires `cursorRecordId`.","schema":{"type":"string","format":"date-time"}},{"name":"cursorRecordId","in":"query","description":"Tie-breaker record id, required when paging with `next`/`prev`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated child step records.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiRequestChildrenResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Query decoded log data for an API trace step

> Returns the decoded request/response payload and error metadata for a\
> record/stage within an API request execution, identified by\
> \`\_expOrImpId\`, \`stage\`, \`groupId\`, and \`recordId\`. If the log content\
> exceeds inline limits or is stored externally, an \`externalReference\`\
> with an S3 key (and optional byte range) is returned — download it via\
> the signed-URL endpoint. The response may be gzip-compressed.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiLogDataRequest":{"type":"object","description":"Query payload for retrieving decoded log data for a step within an API\nrequest execution. Same shape as the flow log-data query; for API Builder\nsteps, `_expOrImpId` may be a MongoDB ObjectId or a builder resource-step\nidentifier (`resStepId`).","required":["_expOrImpId","stage","groupId","recordId"],"properties":{"_expOrImpId":{"type":"string","description":"Export, import, or builder resource-step identifier for the step."},"stage":{"type":"string","description":"Processing stage to fetch data for."},"groupId":{"type":"string","description":"Group identifier for the step's records."},"recordId":{"type":"string","description":"Identifier of the record to fetch."}}},"ApiLogDataResponse":{"type":"object","description":"Decoded log payload for a step, plus any collected error metadata.","required":["logs","errors"],"properties":{"logs":{"type":"array","description":"Decoded log payload entries for the step. Large payloads are not inlined —\nsuch an entry carries an `externalReference[]`, each with a `source.s3Key`;\npass that key to `GET /v1/apis/{_id}/requests/{executionId}/logs/signedURL`\nto download the full content.","items":{"type":"object","properties":{"externalReference":{"type":"array","description":"References to externally stored payload content, present for large payloads.","items":{"type":"object","properties":{"source":{"type":"object","description":"Location of the externally stored content.","properties":{"s3Key":{"type":"string","description":"Relative key to pass to the signed-URL endpoint."}},"additionalProperties":true}},"additionalProperties":true}}},"additionalProperties":true}},"errors":{"type":"array","description":"Error metadata collected while resolving the payload.","items":{"type":"object","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":{"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests/{executionId}/logs/data/query":{"post":{"operationId":"queryApiRequestLogData","tags":["APIs"],"summary":"Query decoded log data for an API trace step","description":"Returns the decoded request/response payload and error metadata for a\nrecord/stage within an API request execution, identified by\n`_expOrImpId`, `stage`, `groupId`, and `recordId`. If the log content\nexceeds inline limits or is stored externally, an `externalReference`\nwith an S3 key (and optional byte range) is returned — download it via\nthe signed-URL endpoint. The response may be gzip-compressed.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"executionId","in":"path","required":true,"description":"The execution id (20-character lowercase hex).","schema":{"type":"string","pattern":"^[0-9a-f]{20}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLogDataRequest"}}}},"responses":{"200":{"description":"Log data (and/or external references) plus error metadata.","headers":{"Content-Encoding":{"description":"May be `gzip` to reduce transfer time for large responses.","schema":{"type":"string","enum":["gzip"]}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiLogDataResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Get a signed URL for a stored API request log payload

> Returns a short-lived signed S3 URL (about 120 seconds expiry) for the\
> provided \`s3Key\` suffix, taken from an \`externalReference\` returned by the\
> log-data query endpoint. The full S3 key is resolved under the execution's\
> own log prefix, so callers can only access logs for this API and execution.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"ApiSignedUrlResponse":{"type":"object","description":"A short-lived signed URL for downloading a stored API request log payload object.","required":["signedURL"],"properties":{"signedURL":{"type":"string","description":"Time-limited signed URL (about 120 seconds) to download the referenced log object."}}},"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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"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/apis/{_id}/requests/{executionId}/logs/signedURL":{"get":{"operationId":"getApiRequestLogSignedUrl","tags":["APIs"],"summary":"Get a signed URL for a stored API request log payload","description":"Returns a short-lived signed S3 URL (about 120 seconds expiry) for the\nprovided `s3Key` suffix, taken from an `externalReference` returned by the\nlog-data query endpoint. The full S3 key is resolved under the execution's\nown log prefix, so callers can only access logs for this API and execution.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"executionId","in":"path","required":true,"description":"The execution id (20-character lowercase hex).","schema":{"type":"string","pattern":"^[0-9a-f]{20}$"}},{"name":"s3Key","in":"query","required":true,"description":"S3 object key suffix relative to the execution's log prefix, typically\nreturned in a prior log-data query `externalReference`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Signed URL for the requested object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSignedUrlResponse"}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## List dependencies of an API

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

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"DependencyResponse":{"type":"object","description":"Map of dependent-resource types to arrays of dependency entries.\nKeys are plural resource type strings (e.g. `flows`, `imports`,\n`connections`). An empty object `{}` means no dependents.\n","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/DependencyEntry"}}},"DependencyEntry":{"type":"object","description":"A single resource that depends on the queried resource.","properties":{"id":{"type":"string","description":"Unique identifier of the dependent resource."},"name":{"type":"string","description":"Display name of the dependent resource."},"paths":{"type":"array","description":"Dot-notation paths within the dependent resource that reference\nthe target resource. `[*]` denotes array elements.","items":{"type":"string"}},"accessLevel":{"type":"string","description":"The caller's access level on the dependent resource."},"dependencyIds":{"type":"object","description":"Map of resource types to arrays of IDs that this dependent\nresource references on the target. Keys are singular or plural\nresource type strings; values are arrays of ID strings.","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["id","name","paths","accessLevel","dependencyIds"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/apis/{_id}/dependencies":{"get":{"operationId":"listApiDependencies","tags":["APIs"],"summary":"List dependencies of an API","description":"Returns the set of resources that depend on the specified resource.\nThe response is an object whose keys are dependent-resource types\n(e.g. `flows`, `imports`) and whose values are arrays of dependency\nentries. An empty object `{}` means no other resources depend on the\ntarget -- 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"}}}}}}
```

## Test-run an API

> Executes the API once in a sandboxed test harness without invoking its public endpoint, and\
> returns the job tree produced by the run. Use this to validate a builder-mode API's request\
> parsing, routing, and response mapping before exposing it externally.\
> \
> The response carries a \`metadata\` map keyed by step id (each value is the ordered list of\
> stage names that ran for that step), the parent \`flowJob\`, and the per-step \`childJobs\[]\`.\
> Inspect a specific step's stages with \`GET /v1/apis/{\_id}/test/run/{runId}/{\_stepId}\`, where\
> \`runId\` is the parent \`flowJob.\_id\`.\
> \
> Test-run invocations do \*\*not\*\* surface in \`GET /v1/apis/{\_id}/logs\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"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"}}}},"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"}}}}},"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/apis/{_id}/test/run":{"post":{"operationId":"testRunApi","tags":["APIs"],"summary":"Test-run an API","description":"Executes the API once in a sandboxed test harness without invoking its public endpoint, and\nreturns the job tree produced by the run. Use this to validate a builder-mode API's request\nparsing, routing, and response mapping before exposing it externally.\n\nThe response carries a `metadata` map keyed by step id (each value is the ordered list of\nstage names that ran for that step), the parent `flowJob`, and the per-step `childJobs[]`.\nInspect a specific step's stages with `GET /v1/apis/{_id}/test/run/{runId}/{_stepId}`, where\n`runId` is the parent `flowJob._id`.\n\nTest-run invocations do **not** surface in `GET /v1/apis/{_id}/logs`.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","description":"Optional test request for the run. When the body is empty or\nomitted, the run replays the API's saved\n`builder.request.mockRequest`.","properties":{"mockRequest":{"type":"object","description":"The simulated request to run instead of the saved\n`builder.request.mockRequest`.","properties":{"body":{"type":"object","description":"Request body for the simulated call."},"pathParams":{"type":"object","description":"Path parameter values for the simulated call."},"queryParams":{"type":"object","description":"Query parameter values for the simulated call."},"headers":{"type":"object","description":"Request headers for the simulated call."}}}},"additionalProperties":true}}}},"responses":{"200":{"description":"The job tree produced by the test run.","content":{"application/json":{"schema":{"type":"object","properties":{"metadata":{"type":"object","description":"Map keyed by step id; each value is the ordered list of stage names that ran for\nthat step.","additionalProperties":{"type":"array","items":{"type":"string"}}},"flowJob":{"type":"object","description":"The parent job for the test run. Its `_id` is the `runId`."},"childJobs":{"type":"array","description":"Per-step child jobs produced during the run.","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Get a step's stages from an API test run

> Returns the per-stage execution detail for a single step of a completed API test run. \`runId\`\
> is the parent \`flowJob.\_id\` returned by \`POST /v1/apis/{\_id}/test/run\`, and \`\_stepId\` is the\
> step id surfaced in that run's \`metadata\` map.\
> \
> Each entry in \`stages\[]\` carries the stage \`name\` (e.g. \`request\`, \`parse\`, \`router\`) plus its\
> \`input\`, \`output\`, and \`errors\`. Stages that did not produce data for a given direction return\
> \`null\` for that field. Top-level \`errors\` aggregates step-level errors.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"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"}}}}},"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/apis/{_id}/test/run/{runId}/{_stepId}":{"get":{"operationId":"getApiTestRunStep","tags":["APIs"],"summary":"Get a step's stages from an API test run","description":"Returns the per-stage execution detail for a single step of a completed API test run. `runId`\nis the parent `flowJob._id` returned by `POST /v1/apis/{_id}/test/run`, and `_stepId` is the\nstep id surfaced in that run's `metadata` map.\n\nEach entry in `stages[]` carries the stage `name` (e.g. `request`, `parse`, `router`) plus its\n`input`, `output`, and `errors`. Stages that did not produce data for a given direction return\n`null` for that field. Top-level `errors` aggregates step-level errors.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"runId","in":"path","required":true,"description":"The parent job id (`flowJob._id`) returned by the test-run request.","schema":{"type":"string"}},{"name":"_stepId","in":"path","required":true,"description":"The step id, as surfaced in the test run's `metadata` map.","schema":{"type":"string"}}],"responses":{"200":{"description":"Per-stage execution detail for the requested step.","content":{"application/json":{"schema":{"type":"object","properties":{"stages":{"type":"array","description":"Ordered stages that ran for this step.","items":{"type":"object","properties":{"name":{"type":"string","description":"Stage name (e.g. `request`, `parse`, `router`)."},"errors":{"description":"Stage-level errors, or `null` when none."},"input":{"description":"Input records the stage received, or `null`."},"output":{"description":"Output records the stage produced, or `null`."}}}},"errors":{"type":"array","description":"Aggregated step-level errors.","items":{"type":"object"}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get request/response captures for an API test-run step

> Returns the request/response captures recorded for a single export or import step of an API\
> test run. \`runId\` is the parent \`flowJob.\_id\` from \`POST /v1/apis/{\_id}/test/run\`, and\
> \`\_stepId\` is the step id from that run's \`metadata\` map.\
> \
> Each entry in \`requests\[]\` is a summary identified by an opaque \`key\`; fetch the full decoded\
> request/response envelope with \`GET /v1/apis/{\_id}/{\_stepId}/requests/{key}\`. A step id that\
> is not an export or import (such as a router) returns a 400 \`invalid\_ref\`, and a step that\
> captured no request/response data returns a 404 \`req\_res\_logs\_not\_found\`.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/apis/{_id}/test/run/{runId}/{_stepId}/logs/requestAndResponse":{"get":{"operationId":"getApiTestRunStepLogs","tags":["APIs"],"summary":"Get request/response captures for an API test-run step","description":"Returns the request/response captures recorded for a single export or import step of an API\ntest run. `runId` is the parent `flowJob._id` from `POST /v1/apis/{_id}/test/run`, and\n`_stepId` is the step id from that run's `metadata` map.\n\nEach entry in `requests[]` is a summary identified by an opaque `key`; fetch the full decoded\nrequest/response envelope with `GET /v1/apis/{_id}/{_stepId}/requests/{key}`. A step id that\nis not an export or import (such as a router) returns a 400 `invalid_ref`, and a step that\ncaptured no request/response data returns a 404 `req_res_logs_not_found`.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"runId","in":"path","required":true,"description":"The parent job id (`flowJob._id`) returned by the test-run request.","schema":{"type":"string"}},{"name":"_stepId","in":"path","required":true,"description":"The step id, as surfaced in the test run's `metadata` map. Must be an export or import step.","schema":{"type":"string"}}],"responses":{"200":{"description":"Request captures recorded for the step.","content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","description":"Captured request summaries for the step.","items":{"type":"object","properties":{"key":{"type":"string","description":"Opaque key for the capture. Resolve the full decoded request/response with\n`GET /v1/apis/{_id}/{_stepId}/requests/{key}`."},"time":{"type":"integer","description":"Capture time, epoch milliseconds."},"method":{"type":"string","description":"HTTP method of the captured request, or `undefined` when not applicable."},"statusCode":{"type":"string","description":"Response status code, as a string."},"stage":{"type":"string","description":"The stage that produced the capture (e.g. `import`)."}}}}}}}}},"400":{"description":"The `_stepId` does not resolve to an export or import step (for example, a router step\nor a malformed id). Use a step id that ran an outbound request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"No request/response data is stored for the requested step — it captured nothing, or the\nrun/step id didn't resolve.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## List captured requests for an API step

> Returns the set of requests captured for a single step of an API. \`\_stepId\` identifies the\
> step within the API's configuration. Each entry in \`requests\[]\` is a captured request summary;\
> follow up with \`GET /v1/apis/{\_id}/{\_stepId}/requests/{key}\` to retrieve one entry in full.\
> \
> An empty \`requests\[]\` simply means nothing is currently stored for this step.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/apis/{_id}/{_stepId}/requests":{"get":{"operationId":"listApiStepRequests","tags":["APIs"],"summary":"List captured requests for an API step","description":"Returns the set of requests captured for a single step of an API. `_stepId` identifies the\nstep within the API's configuration. Each entry in `requests[]` is a captured request summary;\nfollow up with `GET /v1/apis/{_id}/{_stepId}/requests/{key}` to retrieve one entry in full.\n\nAn empty `requests[]` simply means nothing is currently stored for this step.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"_stepId","in":"path","required":true,"description":"The step id within the API's configuration.","schema":{"type":"string"}}],"responses":{"200":{"description":"Captured requests for the step. `requests[]` is empty when nothing is stored.","content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","description":"Captured request entries for this step.","items":{"type":"object"}}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Get one captured request for an API step by key

> Returns the full captured request/response envelope for one entry of an API step, looked up by\
> the opaque \`key\` values surfaced in \`GET /v1/apis/{\_id}/{\_stepId}/requests\`. Matches the exact\
> entry whose key is provided — there is no partial-match query on this endpoint.\
> \
> Use the \`key\` exactly as returned by the parent listing; do not construct one manually. A 404\
> means the key has expired from retention or was never captured.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/apis/{_id}/{_stepId}/requests/{key}":{"get":{"operationId":"getApiStepRequest","tags":["APIs"],"summary":"Get one captured request for an API step by key","description":"Returns the full captured request/response envelope for one entry of an API step, looked up by\nthe opaque `key` values surfaced in `GET /v1/apis/{_id}/{_stepId}/requests`. Matches the exact\nentry whose key is provided — there is no partial-match query on this endpoint.\n\nUse the `key` exactly as returned by the parent listing; do not construct one manually. A 404\nmeans the key has expired from retention or was never captured.","parameters":[{"name":"_id","in":"path","required":true,"description":"The API id.","schema":{"type":"string","format":"objectId"}},{"name":"_stepId","in":"path","required":true,"description":"The step id within the API's configuration.","schema":{"type":"string"}},{"name":"key","in":"path","required":true,"description":"Opaque request key from the parent `GET /v1/apis/{_id}/{_stepId}/requests` listing. Use the\n`key` exactly as returned; do not construct one manually.","schema":{"type":"string"}}],"responses":{"200":{"description":"The full captured request/response envelope for the entry.","content":{"application/json":{"schema":{"type":"object","description":"Decoded request/response envelope for the captured entry."}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Clone an API

> Clones a builder-mode API along with the resources it depends on (such as its\
> backing import) and returns a manifest of every resource created.\
> \
> The request body is required: \`version\` must be supplied, and the cloned API's\
> combination of \`version\`, \`method\`, and \`relativeURI\` must be unique. Reusing all\
> three returns a 422 \`clone\_api\_already\_exists\`. Pass \`\_integrationId\` to create the\
> clone inside an integration — when omitted, the clone is created standalone rather\
> than inheriting the source API's integration.\
> \
> Only \*\*builder-type\*\* APIs can be cloned — cloning any other API type returns a 400\
> \`clone\_not\_supported\`.\
> \
> To check for a version/method/relativeURI conflict without creating anything, call\
> \`POST /v1/apis/{\_id}/clone/validate\` first.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"404-not-found":{"description":"Not found. The requested resource does not exist or is not visible to the caller.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/apis/{_id}/clone":{"post":{"operationId":"cloneApi","tags":["APIs"],"summary":"Clone an API","description":"Clones a builder-mode API along with the resources it depends on (such as its\nbacking import) and returns a manifest of every resource created.\n\nThe request body is required: `version` must be supplied, and the cloned API's\ncombination of `version`, `method`, and `relativeURI` must be unique. Reusing all\nthree returns a 422 `clone_api_already_exists`. Pass `_integrationId` to create the\nclone inside an integration — when omitted, the clone is created standalone rather\nthan inheriting the source API's integration.\n\nOnly **builder-type** APIs can be cloned — cloning any other API type returns a 400\n`clone_not_supported`.\n\nTo check for a version/method/relativeURI conflict without creating anything, call\n`POST /v1/apis/{_id}/clone/validate` first.","parameters":[{"name":"_id","in":"path","required":true,"description":"The id of the API to clone.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["version"],"properties":{"version":{"type":"string","description":"Version identifier for the cloned API. The cloned API's combination of\n`version`, `method`, and `relativeURI` must be unique — reusing all three\nreturns a 422 `clone_api_already_exists`."},"name":{"type":"string","description":"Name for the cloned API. Defaults to a copy of the source API's name when omitted."},"_integrationId":{"type":"string","format":"objectId","description":"Integration the cloned API is created in. When omitted, the clone is created\nstandalone — it does not inherit the source API's integration."}}}}}},"responses":{"201":{"description":"The clone was created. Returns a manifest of every resource the clone created —\nthe new API plus any dependencies it copied (imports, scripts).","content":{"application/json":{"schema":{"type":"array","description":"Manifest of resources created by the clone.","items":{"type":"object","properties":{"model":{"type":"string","description":"Model name of the created resource (e.g. `Api`, `Import`)."},"_id":{"type":"string","format":"objectId","description":"Unique id of the created resource."}}}}}}},"400":{"description":"The request was rejected. Common causes: the body omits the required `version`\nfield (`required_field_missing`), or the target API is not a builder-type API\n(`clone_not_supported` — only builder APIs can be cloned).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"$ref":"#/components/responses/404-not-found"},"422":{"description":"An API with the same `version`, `method`, and `relativeURI` already exists. Clone\nwith a different `version` (or change the method/URI) to create a distinct API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Validate an API clone

> Dry-run check for \`POST /v1/apis/{\_id}/clone\`. Verifies that cloning the\
> API to the target \`version\` would not collide with an existing API route\
> — the clone keeps the source API's \`method\` and \`relativeURI\`, so the\
> target \`version\` + \`method\` + \`relativeURI\` combination must not conflict\
> with an API that is already registered in the account. Nothing is created\
> or modified.\
> \
> Returns \`canClone: true\` when the route is free, \`false\` when it\
> conflicts — pick a different \`version\` before calling\
> \`POST /v1/apis/{\_id}/clone\`. Only \*\*builder-type\*\* APIs can be validated;\
> a script-type API returns 404, the same as an unknown id.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/apis/{_id}/clone/validate":{"post":{"operationId":"validateApiClone","tags":["APIs"],"summary":"Validate an API clone","description":"Dry-run check for `POST /v1/apis/{_id}/clone`. Verifies that cloning the\nAPI to the target `version` would not collide with an existing API route\n— the clone keeps the source API's `method` and `relativeURI`, so the\ntarget `version` + `method` + `relativeURI` combination must not conflict\nwith an API that is already registered in the account. Nothing is created\nor modified.\n\nReturns `canClone: true` when the route is free, `false` when it\nconflicts — pick a different `version` before calling\n`POST /v1/apis/{_id}/clone`. Only **builder-type** APIs can be validated;\na script-type API returns 404, the same as an unknown id.","parameters":[{"name":"_id","in":"path","required":true,"description":"The id of the API to validate cloning for.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["version"],"properties":{"version":{"type":"string","description":"Version identifier the clone would be created under. Omitting\nit returns a 400 `required_field_missing`."}}}}}},"responses":{"200":{"description":"Validation result. Returned for both outcomes — check `canClone`.","content":{"application/json":{"schema":{"type":"object","properties":{"canClone":{"type":"boolean","description":"When true, the target `version` + `method` + `relativeURI`\nroute is free and the clone can be created. When false, the\nroute conflicts with an existing API — choose a different\n`version`."}}}}}},"400":{"description":"The body omits the required `version` field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"The API does not exist, is not visible to the caller, or is not a\nbuilder-type API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get a downloadable template for an API

> Packages a builder-mode API as an installable template and returns a\
> signed S3 URL where the template \`.zip\` can be downloaded. The URL is\
> pre-signed and short-lived (approximately 15 minutes), so fetch the file\
> promptly; call the endpoint again for a fresh URL.\
> \
> The \`.zip\` contains the API definition plus every resource it references\
> — imports, exports, connections, and scripts — grouped into one folder\
> per resource type, with an \`integration.json\` manifest at the root.\
> \
> Only \*\*builder-type\*\* APIs can be exported — requesting a script-type\
> API returns 404, the same as an unknown id. Requires the\
> \`create:api:template\` permission.

```json
{"openapi":"3.2.0","info":{"title":"APIs","version":"1.0.0"},"tags":[{"name":"APIs","description":"APIs expose integration logic as HTTP endpoints that external systems can invoke.\n\nTwo modes:\n- **Builder** — visual configuration with request/response mapping, routing, and transformations\n- **Script** — custom JavaScript handler function for full control\n\nEach API gets a public URL: `https://api.integrator.io/apis/{version}/{relativeURI}`\n\n## API schema\n\n{% openapi-schemas spec=\"api\" schemas=\"API\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}},"schemas":{"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}}},"paths":{"/v1/apis/{_id}/template":{"get":{"operationId":"getApiTemplate","tags":["APIs"],"summary":"Get a downloadable template for an API","description":"Packages a builder-mode API as an installable template and returns a\nsigned S3 URL where the template `.zip` can be downloaded. The URL is\npre-signed and short-lived (approximately 15 minutes), so fetch the file\npromptly; call the endpoint again for a fresh URL.\n\nThe `.zip` contains the API definition plus every resource it references\n— imports, exports, connections, and scripts — grouped into one folder\nper resource type, with an `integration.json` manifest at the root.\n\nOnly **builder-type** APIs can be exported — requesting a script-type\nAPI returns 404, the same as an unknown id. Requires the\n`create:api:template` permission.","parameters":[{"name":"_id","in":"path","required":true,"description":"The id of the API to export.","schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"Signed download URL for the API template zip.","content":{"application/json":{"schema":{"type":"object","properties":{"signedURL":{"type":"string","format":"uri","description":"Pre-signed, short-lived S3 URL to download the template `.zip`."},"key":{"type":"string","description":"S3 object key for the generated template `.zip`, named `<apiId>.zip`."}}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"404":{"description":"The API does not exist, is not visible to the caller, or is not a\nbuilder-type API (script-type APIs cannot be exported as templates).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://developer.celigo.com/api/api-reference/apis.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
