> 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/templates.md).

# Templates

Templates are pre-built integration configurations that Partners publish to the Celigo marketplace for other users to install.

The template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.

All endpoints require a **Partner account** — non-partner callers receive 403 `access_restricted`.

### Template schema

## The Template object

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"components":{"schemas":{"Template":{"type":"object","required":["_id","name","lastModified"],"description":"A template resource as returned by the API.\n\nFields that are `false` or empty may be omitted from the response\n(e.g. `published` is omitted when the template is unpublished,\n`imageURL` is omitted when not set).","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Omitted when never\nset; may be an empty string when the field was cleared."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. May be\nan empty string when the field was cleared; legacy values may\nlack a scheme (e.g. `www.example.com`)."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Whether the template is published to the marketplace. Omitted\nfrom the response when `false`. Can only be set to `true` after\na template zip file has been uploaded via `GET /v1/s3SignedURL`."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers associated with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."},"free":{"type":"boolean","description":"When true, the template is free to install with no license requirement.","readOnly":true},"numInstalls":{"type":"integer","description":"Number of times this template has been installed.","readOnly":true,"minimum":0}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}}}}
```

## List templates

> Returns all templates owned by the authenticated Partner account.\
> The response is a flat JSON array with no pagination.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"After":{"name":"after","in":"query","required":false,"description":"Opaque cursor for forward pagination. Pass the value from the `Link`\nresponse header (`rel=\"next\"`) to fetch the next page.","schema":{"type":"string"}}},"schemas":{"Template":{"type":"object","required":["_id","name","lastModified"],"description":"A template resource as returned by the API.\n\nFields that are `false` or empty may be omitted from the response\n(e.g. `published` is omitted when the template is unpublished,\n`imageURL` is omitted when not set).","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Omitted when never\nset; may be an empty string when the field was cleared."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. May be\nan empty string when the field was cleared; legacy values may\nlack a scheme (e.g. `www.example.com`)."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Whether the template is published to the marketplace. Omitted\nfrom the response when `false`. Can only be set to `true` after\na template zip file has been uploaded via `GET /v1/s3SignedURL`."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers associated with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."},"free":{"type":"boolean","description":"When true, the template is free to install with no license requirement.","readOnly":true},"numInstalls":{"type":"integer","description":"Number of times this template has been installed.","readOnly":true,"minimum":0}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/templates":{"get":{"operationId":"listTemplates","tags":["Templates"],"parameters":[{"name":"limit","in":"query","description":"Maximum number of records to return per page.","schema":{"type":"integer","minimum":1}},{"$ref":"#/components/parameters/After"}],"summary":"List templates","description":"Returns all templates owned by the authenticated Partner account.\nThe response is a flat JSON array with no pagination.","responses":{"200":{"description":"Array of template resources.","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/Template"}}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"}}}}}}
```

## Create a template

> Creates a new integration template. Only \`name\` is required; all\
> other fields are optional. Upload a zip via \`GET /v1/s3SignedURL\`\
> before attempting to publish.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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":{"TemplateInput":{"type":"object","description":"Request body for creating or updating a template. `name` is always\nrequired, even on PUT. `published` can only be set to `true` after\nuploading a template zip via `GET /v1/s3SignedURL`.","required":["name"],"properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Send an empty string to\nclear it."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. Send an\nempty string to clear it."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Set to `true` to publish the template to the marketplace (requires\na zip upload first). Set to `false` to unpublish."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers to associate with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."}}},"Template":{"type":"object","required":["_id","name","lastModified"],"description":"A template resource as returned by the API.\n\nFields that are `false` or empty may be omitted from the response\n(e.g. `published` is omitted when the template is unpublished,\n`imageURL` is omitted when not set).","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Omitted when never\nset; may be an empty string when the field was cleared."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. May be\nan empty string when the field was cleared; legacy values may\nlack a scheme (e.g. `www.example.com`)."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Whether the template is published to the marketplace. Omitted\nfrom the response when `false`. Can only be set to `true` after\na template zip file has been uploaded via `GET /v1/s3SignedURL`."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers associated with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."},"free":{"type":"boolean","description":"When true, the template is free to install with no license requirement.","readOnly":true},"numInstalls":{"type":"integer","description":"Number of times this template has been installed.","readOnly":true,"minimum":0}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\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/templates":{"post":{"operationId":"createTemplate","tags":["Templates"],"summary":"Create a template","description":"Creates a new integration template. Only `name` is required; all\nother fields are optional. Upload a zip via `GET /v1/s3SignedURL`\nbefore attempting to publish.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInput"}}}},"responses":{"201":{"description":"Template created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"422":{"$ref":"#/components/responses/422-unprocessable-entity"}}}}}}
```

## Get a template

> Returns a single template by ID.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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":{"Template":{"type":"object","required":["_id","name","lastModified"],"description":"A template resource as returned by the API.\n\nFields that are `false` or empty may be omitted from the response\n(e.g. `published` is omitted when the template is unpublished,\n`imageURL` is omitted when not set).","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Omitted when never\nset; may be an empty string when the field was cleared."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. May be\nan empty string when the field was cleared; legacy values may\nlack a scheme (e.g. `www.example.com`)."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Whether the template is published to the marketplace. Omitted\nfrom the response when `false`. Can only be set to `true` after\na template zip file has been uploaded via `GET /v1/s3SignedURL`."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers associated with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."},"free":{"type":"boolean","description":"When true, the template is free to install with no license requirement.","readOnly":true},"numInstalls":{"type":"integer","description":"Number of times this template has been installed.","readOnly":true,"minimum":0}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"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/templates/{_id}":{"get":{"operationId":"getTemplateById","tags":["Templates"],"summary":"Get a template","description":"Returns a single template by ID.","parameters":[{"name":"_id","in":"path","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"200":{"description":"The template resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Update a template

> Replaces the template's fields with the values in the request body.\
> Omitted optional fields retain their current values. \`name\` is\
> required on every PUT, even if unchanged.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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":{"TemplateInput":{"type":"object","description":"Request body for creating or updating a template. `name` is always\nrequired, even on PUT. `published` can only be set to `true` after\nuploading a template zip via `GET /v1/s3SignedURL`.","required":["name"],"properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Send an empty string to\nclear it."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. Send an\nempty string to clear it."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Set to `true` to publish the template to the marketplace (requires\na zip upload first). Set to `false` to unpublish."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers to associate with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."}}},"Template":{"type":"object","required":["_id","name","lastModified"],"description":"A template resource as returned by the API.\n\nFields that are `false` or empty may be omitted from the response\n(e.g. `published` is omitted when the template is unpublished,\n`imageURL` is omitted when not set).","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Display name of the template."},"description":{"type":"string","description":"Longer description shown in the marketplace."},"imageURL":{"type":"string","description":"URL of the template's marketplace image. Omitted when never\nset; may be an empty string when the field was cleared."},"websiteURL":{"type":"string","description":"URL to the partner's website or template landing page. May be\nan empty string when the field was cleared; legacy values may\nlack a scheme (e.g. `www.example.com`)."},"contactEmail":{"type":"string","description":"Contact email(s) for template support — a single address or a\ncomma-separated list of addresses."},"published":{"type":"boolean","description":"Whether the template is published to the marketplace. Omitted\nfrom the response when `false`. Can only be set to `true` after\na template zip file has been uploaded via `GET /v1/s3SignedURL`."},"applications":{"type":"array","items":{"type":"string"},"description":"Application identifiers associated with this template.\nValues may be application slugs (e.g. `salesforce`) or\nMongo ObjectIds."},"free":{"type":"boolean","description":"When true, the template is free to install with no license requirement.","readOnly":true},"numInstalls":{"type":"integer","description":"Number of times this template has been installed.","readOnly":true,"minimum":0}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}},"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/templates/{_id}":{"put":{"operationId":"updateTemplate","tags":["Templates"],"summary":"Update a template","description":"Replaces the template's fields with the values in the request body.\nOmitted optional fields retain their current values. `name` is\nrequired on every PUT, even if unchanged.","parameters":[{"name":"_id","in":"path","required":true,"schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInput"}}}},"responses":{"200":{"description":"Updated template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}},"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":{"description":"Template zip has not been uploaded yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Delete a template

> Permanently deletes a template.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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"]}}}},"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/templates/{_id}":{"delete":{"operationId":"deleteTemplate","tags":["Templates"],"summary":"Delete a template","description":"Permanently deletes a template.","parameters":[{"name":"_id","in":"path","required":true,"schema":{"type":"string","format":"objectId"}}],"responses":{"204":{"description":"Template deleted."},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"$ref":"#/components/responses/404-not-found"}}}}}}
```

## Install an integration from a template

> Installs an integration from a published template. The caller provides a\
> \`connectionMap\` that maps each template-defined connection ID to an actual\
> connection ID in the caller's account. Every template connection must\
> appear as a key in \`connectionMap\`.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/template/{_id}":{"post":{"operationId":"installTemplate","tags":["Templates"],"summary":"Install an integration from a template","description":"Installs an integration from a published template. The caller provides a\n`connectionMap` that maps each template-defined connection ID to an actual\nconnection ID in the caller's account. Every template connection must\nappear as a key in `connectionMap`.","parameters":[{"name":"_id","in":"path","required":true,"description":"The template ID to install from.","schema":{"type":"string","format":"objectId"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Connection mapping from template connection IDs to the caller's\nreal connection IDs.","properties":{"connectionMap":{"type":"object","description":"Keys are connection `_id` values from the template; values are\nthe caller's own connection `_id` values that should replace\nthem during install.","additionalProperties":{"type":"string"}}},"required":["connectionMap"]}}}},"responses":{"200":{"description":"Template installed successfully.","content":{"application/json":{"schema":{"type":"object","description":"The created integration and related resources.","additionalProperties":true}}}},"400":{"description":"Missing or empty `connectionMap`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"description":"Template not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Connection IDs in `connectionMap` do not match the template's\nexpected connection IDs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Preview a template install from an uploaded zip

> Previews the resources that would be created by installing a template\
> from an uploaded zip file. The \`runKey\` query parameter ties this request\
> to a previously uploaded zip (obtained from \`GET /v1/s3SignedURL\`).

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/template/preview":{"get":{"operationId":"previewTemplateInstall","tags":["Templates"],"summary":"Preview a template install from an uploaded zip","description":"Previews the resources that would be created by installing a template\nfrom an uploaded zip file. The `runKey` query parameter ties this request\nto a previously uploaded zip (obtained from `GET /v1/s3SignedURL`).","parameters":[{"name":"runKey","in":"query","required":true,"description":"The `runKey` returned by `GET /v1/s3SignedURL` after uploading the\ntemplate zip file.","schema":{"type":"string"}}],"responses":{"200":{"description":"Preview of resources the template would create.","content":{"application/json":{"schema":{"type":"object","description":"Preview envelope with resource docs.","additionalProperties":true}}}},"400":{"description":"Missing required `runKey` query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"description":"The `runKey` does not match any uploaded zip.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Install a template from an uploaded zip

> Installs a template from a previously uploaded zip file. The \`runKey\`\
> in the request body ties this request to the zip upload (obtained from\
> \`GET /v1/s3SignedURL\`).\
> \
> The zip carries connection definitions without credentials, and the\
> installed integration receives new connection \`\_id\`s. Configure each\
> connection in the new integration before running its flows; connection\
> \`\_id\`s that existed only in the zip are not preserved.

```json
{"openapi":"3.2.0","info":{"title":"Templates","version":"1.0.0"},"tags":[{"name":"Templates","description":"Templates are pre-built integration configurations that Partners\npublish to the Celigo marketplace for other users to install.\n\nThe template lifecycle is: create → upload zip (via `GET /v1/s3SignedURL`) → publish.\n\nAll endpoints require a **Partner account** — non-partner callers\nreceive 403 `access_restricted`.\n\n## Template schema\n\n{% openapi-schemas spec=\"template\" schemas=\"Template\" 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"]}}}},"403-forbidden":{"description":"Forbidden. The authenticated caller does not have permission to perform this operation.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/integrations/template":{"post":{"operationId":"installTemplateFromZip","tags":["Templates"],"summary":"Install a template from an uploaded zip","description":"Installs a template from a previously uploaded zip file. The `runKey`\nin the request body ties this request to the zip upload (obtained from\n`GET /v1/s3SignedURL`).\n\nThe zip carries connection definitions without credentials, and the\ninstalled integration receives new connection `_id`s. Configure each\nconnection in the new integration before running its flows; connection\n`_id`s that existed only in the zip are not preserved.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"The `runKey` from the zip upload.","properties":{"runKey":{"type":"string","description":"The `runKey` returned by `GET /v1/s3SignedURL` after uploading\nthe template zip file."}},"required":["runKey"]}}}},"responses":{"200":{"description":"Template installed from uploaded zip.","content":{"application/json":{"schema":{"type":"object","description":"The created integration and related resources.","additionalProperties":true}}}},"400":{"description":"Missing required `runKey` in request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/401-unauthorized"},"403":{"$ref":"#/components/responses/403-forbidden"},"404":{"description":"The `runKey` does not match any uploaded zip.","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/templates.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.
